Forráskód Böngészése

Port radius server

TelenkovDmitry 7 éve
szülő
commit
c5ec3a916b
43 módosított fájl, 9957 hozzáadás és 1 törlés
  1. 248 0
      modules/radius/radius_user.c
  2. 47 0
      modules/radius/radius_user.h
  3. 45 0
      projects/iar/bt-670x.ewp
  4. 15 0
      thirdparty/FreeRadius/include/Makefile.am
  5. 572 0
      thirdparty/FreeRadius/include/Makefile.in
  6. 556 0
      thirdparty/FreeRadius/include/freeradius-client.h
  7. 188 0
      thirdparty/FreeRadius/include/includes.h
  8. 53 0
      thirdparty/FreeRadius/include/messages.h
  9. 28 0
      thirdparty/FreeRadius/include/pathnames.h
  10. 32 0
      thirdparty/FreeRadius/lib/Makefile.am
  11. 682 0
      thirdparty/FreeRadius/lib/Makefile.in
  12. 893 0
      thirdparty/FreeRadius/lib/avpair.c
  13. 392 0
      thirdparty/FreeRadius/lib/buildreq.c
  14. 137 0
      thirdparty/FreeRadius/lib/clientid.c
  15. 939 0
      thirdparty/FreeRadius/lib/config.c
  16. 501 0
      thirdparty/FreeRadius/lib/dict.c
  17. 138 0
      thirdparty/FreeRadius/lib/env.c
  18. 49 0
      thirdparty/FreeRadius/lib/fr_log.c
  19. 251 0
      thirdparty/FreeRadius/lib/fr_md5.c
  20. 86 0
      thirdparty/FreeRadius/lib/fr_md5.h
  21. 56 0
      thirdparty/FreeRadius/lib/fr_options.h
  22. 184 0
      thirdparty/FreeRadius/lib/ip_util.c
  23. 29 0
      thirdparty/FreeRadius/lib/rc-md5.c
  24. 28 0
      thirdparty/FreeRadius/lib/rc-md5.h
  25. 863 0
      thirdparty/FreeRadius/lib/sendserver.c
  26. 389 0
      thirdparty/FreeRadius/lib/util.c
  27. 50 0
      thirdparty/FreeRadius/lib/util.h
  28. 103 0
      thirdparty/FreeRadius/radius_config.h
  29. 212 0
      thirdparty/FreeRadius/radius_user.c
  30. 44 0
      thirdparty/FreeRadius/radius_user.h
  31. 28 0
      thirdparty/FreeRadius/src/Makefile.am
  32. 706 0
      thirdparty/FreeRadius/src/Makefile.in
  33. 84 0
      thirdparty/FreeRadius/src/local.c
  34. 150 0
      thirdparty/FreeRadius/src/radacct.c
  35. 156 0
      thirdparty/FreeRadius/src/radembedded.c
  36. 96 0
      thirdparty/FreeRadius/src/radexample.c
  37. 197 0
      thirdparty/FreeRadius/src/radius.c
  38. 183 0
      thirdparty/FreeRadius/src/radiusclient.c
  39. 388 0
      thirdparty/FreeRadius/src/radlogin.c
  40. 25 0
      thirdparty/FreeRadius/src/radlogin.h
  41. 130 0
      thirdparty/FreeRadius/src/radstatus.c
  42. 3 0
      user/init_task.c
  43. 1 1
      user/main.h

+ 248 - 0
modules/radius/radius_user.c

@@ -0,0 +1,248 @@
+/********************************* (C) РОТЕК ***********************************
+ * @module  template
+ * @file    template.c
+ * @version 1.0.0
+ * @date    XX.XX.XXXX
+ * $brief   template
+ *******************************************************************************
+ * @history     Version  Author         Comment
+ * XX.XX.XXXX   1.0.0    Telenkov D.A.  First release.
+ *******************************************************************************
+ */
+
+#include "stm32f4xx.h"  
+#include "radius_user.h"
+
+#include "FreeRTOS.h"
+#include "task.h"
+
+#include "freeradius-client.h"
+#include "fr_options.h"
+
+rc_handle	rcHandle;
+
+int auth_order = AUTH_LOCAL_SND;
+int login_tries = 4;
+int login_timeout = 60;
+char* nologin = "?";
+char* issue = "?";
+char* authserver = "192.168.1.2:1645";
+char* acctserver = "0";
+char* servers = "?";
+char* dictionary = "?";
+char *login_radius = "?";
+char *mapfile = "?";
+char *default_realm = NULL;
+int radius_timeout = 10;
+int radius_retries = 3;
+int radius_deadtime = 0;
+char *bindaddr = "*";
+char *login_local = "?";
+
+OPTION      rcOptions[] = {
+{"auth_order",	 	OT_AUO, ST_UNDEF, (void*)&auth_order}, // AUTH_LOCAL_FST AUTH_RADIUS_FST AUTH_LOCAL_SND AUTH_RADIUS_SND
+{"login_tries",	 	OT_INT, ST_UNDEF, (void*)&login_tries},
+{"login_timeout",	OT_INT, ST_UNDEF, (void*)&login_timeout},
+{"nologin",		    OT_STR, ST_UNDEF, NULL},
+{"issue",		    OT_STR, ST_UNDEF, NULL},
+// RADIUS specific options 
+{"authserver",		OT_SRV, ST_UNDEF, (void*)&authserver},
+{"acctserver",		OT_SRV, ST_UNDEF, (void*)&acctserver},
+{"servers",		    OT_STR, ST_UNDEF, (void*)&servers},
+{"dictionary",		OT_STR, ST_UNDEF, (void*)&dictionary},
+{"login_radius",	OT_STR, ST_UNDEF, (void*)&login_radius},
+{"mapfile",		    OT_STR, ST_UNDEF, (void*)&mapfile},
+{"default_realm",	OT_STR, ST_UNDEF, (void*)&default_realm},
+{"radius_timeout",	OT_INT, ST_UNDEF, (void*)&radius_timeout},
+{"radius_retries",	OT_INT,	ST_UNDEF, (void*)&radius_retries},
+{"radius_deadtime",	OT_INT, ST_UNDEF, (void*)&radius_deadtime},
+{"bindaddr",		OT_STR, ST_UNDEF, (void*)&bindaddr},
+// local options 
+{"login_local",		OT_STR, ST_UNDEF, (void*)&login_local},
+};
+
+DICT_ATTR   attr_1;
+DICT_ATTR   attr_2;
+DICT_ATTR   attr_3;
+
+static char fr_msg[PW_MAX_MSG_SIZE];
+
+
+void FR_Login(char* login, char* pas)
+{
+    VALUE_PAIR* send;
+    VALUE_PAIR* received;
+    uint32_t	service;
+    
+    
+    memset(fr_msg, 0, PW_MAX_MSG_SIZE);
+  
+    // Формирование атрибутов
+    // 1. User name
+    strncpy(attr_1.name, login, strlen(login));
+    attr_1.value = 1;
+    attr_1.type = PW_TYPE_STRING;
+    attr_1.next = NULL;
+    
+    // 2. Password
+    strncpy(attr_2.name, pas, strlen(pas));
+    attr_2.value = 2;
+    attr_2.type = PW_TYPE_STRING;
+    attr_2.next = &attr_1;
+    
+    // 3. Service type
+    strcpy(attr_3.name, "Service-Type");
+    attr_3.value = 6;
+    attr_3.type = PW_TYPE_INTEGER;
+    attr_3.next = &attr_2;
+    
+    rcHandle.dictionary_attributes = &attr_3;
+    
+    
+}
+
+/**
+  * @brief  
+  */
+int RD_TestInit(void)
+{
+    int         result;
+	char		username[128];
+	char        passwd[AUTH_PASS_LEN + 1];
+	VALUE_PAIR 	*send, *received;
+	uint32_t	service;
+	char 		msg[PW_MAX_MSG_SIZE], username_realm[256];
+	char		*default_realm;
+	  
+    // Моя подготовка 
+    memset(username, 0, 128);
+    memset(passwd, 0, AUTH_PASS_LEN + 1);
+    memset(msg, 0, PW_MAX_MSG_SIZE);
+    memset(username_realm, 0, 256);
+    
+    
+    // Просто копируем структуру настроек которая жесто задана
+    rc_read_config(&rcHandle);
+   
+    // Словарь пока опускаем и не инициализируем
+    //if (rc_read_dictionary(&rcHandle, rc_conf_str(&rcHandle, "dictionary")) != 0)
+	//	return ERROR_RC;
+  
+    // Заполняем словарь
+    // 1. User name
+    strcpy(attr_1.name, "test1");
+    attr_1.value = 1;
+    attr_1.type = PW_TYPE_STRING;
+    attr_1.next = NULL;
+    
+    // 2. Password
+    strcpy(attr_2.name, "12345");
+    attr_2.value = 2;
+    attr_2.type = PW_TYPE_STRING;
+    attr_2.next = &attr_1;
+    
+    // 3. Service type
+    strcpy(attr_3.name, "Service-Type");
+    attr_3.value = 6;
+    attr_3.type = PW_TYPE_INTEGER;
+    attr_3.next = &attr_2;
+    
+/*    
+    attr_3.value = 244;
+    attr_3.type = PW_TYPE_STRING;
+    attr_3.next = &attr_2;
+*/    
+    rcHandle.dictionary_attributes = &attr_3;
+    
+    // Не понял что за параметра, пока NULL
+    //default_realm = rc_conf_str(rh, "default_realm");
+    default_realm = NULL;
+
+    // Рараметры ожидаются от пользователя
+    //strncpy(username, "dtelenkov", 9);
+    strncpy(username, "test1", 5);
+    strncpy(passwd, "12345", 5);
+    //strncpy(username, rc_getstr (rh, "login: ",1), sizeof(username));
+	//strncpy (passwd, rc_getstr(rh, "Password: ",0), sizeof (passwd));
+    
+    send = NULL;
+        
+    /*
+	 * Fill in User-Name
+	 */
+
+	strncpy(username_realm, username, sizeof(username_realm));
+
+	/* Append default realm */
+    /*
+	if ((strchr(username_realm, '@') == NULL) && default_realm &&
+	    (*default_realm != '\0'))
+	{
+		strncat(username_realm, "@", sizeof(username_realm)-strlen(username_realm)-1);
+		strncat(username_realm, default_realm, sizeof(username_realm)-strlen(username_realm)-1);
+	}
+    */
+    
+	if (rc_avpair_add(&rcHandle, &send, PW_USER_NAME, username_realm, -1, 0) == NULL)
+		return ERROR_RC;
+    
+	/*
+	 * Fill in User-Password
+	 */
+	if (rc_avpair_add(&rcHandle, &send, PW_USER_PASSWORD, passwd, -1, 0) == NULL)
+		return ERROR_RC;
+
+	/*
+	 * Fill in Service-Type
+	 */
+	service = PW_AUTHENTICATE_ONLY;
+	if (rc_avpair_add(&rcHandle, &send, PW_SERVICE_TYPE, &service, -1, 0) == NULL)
+		return ERROR_RC;
+#if 1
+	result = rc_auth(&rcHandle, 0, send, &received, msg);
+
+	if (result == OK_RC)
+	{
+		fprintf(stderr, "\"%s\" RADIUS Authentication OK\n", username);
+	}
+	else
+	{
+		fprintf(stderr, "\"%s\" RADIUS Authentication failure (RC=%i)\n", username, result);
+	}
+
+	
+#endif
+	send = NULL;
+    
+    return 0;
+}
+
+void initFdsets(fdsets *sets)
+{
+    memset((sets)->buf1, 0xab, 8); 
+    memset((sets)->buf2, 0xab, 8); 
+    memset((sets)->buf3, 0xab, 8); 
+    memset((sets)->buf4, 0xab, 8); 
+}
+
+bool recvSelect(fdsets *sets, int *socket, uint32_t timeout)
+{
+    struct timeval tv;
+
+    tv.tv_sec = 0;
+    tv.tv_usec = timeout * 1000;
+      
+    FD_ZERO(&(sets->readset));
+    FD_SET(*socket, &sets->readset);
+    FD_ZERO(&sets->errset);
+    FD_SET(*socket, &sets->errset);
+        
+    lwip_select(*socket + 1, &sets->readset, NULL, &sets->errset, &tv);
+        
+    if (FD_ISSET(*socket, &sets->readset)) 
+        return true;
+
+    return false;
+}
+
+/********************************* (C) РОТЕК **********************************/

+ 47 - 0
modules/radius/radius_user.h

@@ -0,0 +1,47 @@
+/******************************* (C) LiteMesh **********************************
+ * @module  template
+ * @file    template.h
+ * @version 1.0.0
+ * @date    XX.XX.XXXX
+ * $brief   template
+ *******************************************************************************
+ * @history     Version  Author         Comment
+ * XX.XX.XXXX   1.0.0    Telenkov D.A.  First release.
+ *******************************************************************************
+ */
+
+/* Define to prevent recursive  ----------------------------------------------*/
+#ifndef __RADIUS_USER_H
+#define __RADIUS_USER_H
+
+#include "lwip/sockets.h"
+#include <stdbool.h>
+
+
+typedef struct 
+{
+    u8_t   buf1[8];
+    fd_set readset;
+    u8_t   buf2[8];
+    fd_set writeset;
+    u8_t   buf3[8];
+    fd_set errset;
+    u8_t   buf4[8];
+  
+} fdsets;
+
+void FR_Login(char* login, char* pas);
+
+/**
+  * @brief  
+  */
+int RD_TestInit(void);
+
+
+void initFdsets(fdsets *sets);
+
+bool recvSelect(fdsets *sets, int *socket, uint32_t timeout);
+
+#endif /* #ifndef __RADIUS_USER_H */
+
+/****************************** (C) LiteMesh ***************** end of file ****/

+ 45 - 0
projects/iar/bt-670x.ewp

@@ -345,6 +345,9 @@
           <state>$PROJ_DIR$\..\..\thirdparty\lwip\arch</state>
           <state>$PROJ_DIR$\..\..\thirdparty\PolarSSL\include\polarssl</state>
           <state>$PROJ_DIR$\..\..\thirdparty\PolarSSL\include</state>
+          <state>$PROJ_DIR$\..\..\thirdparty\FreeRadius</state>
+          <state>$PROJ_DIR$\..\..\thirdparty\FreeRadius\include</state>
+          <state>$PROJ_DIR$\..\..\thirdparty\FreeRadius\lib</state>
         </option>
         <option>
           <name>CCStdIncCheck</name>
@@ -2055,6 +2058,12 @@
         <name>$PROJ_DIR$\..\..\modules\monitor\ups_monitor.c</name>
       </file>
     </group>
+    <group>
+      <name>radius</name>
+      <file>
+        <name>$PROJ_DIR$\..\..\modules\radius\radius_user.c</name>
+      </file>
+    </group>
     <group>
       <name>STM32F4x7_ETH_Driver</name>
       <file>
@@ -2217,6 +2226,42 @@
   </group>
   <group>
     <name>thirdparty</name>
+    <group>
+      <name>freeradius</name>
+      <group>
+        <name>lib</name>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\FreeRadius\lib\avpair.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\FreeRadius\lib\buildreq.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\FreeRadius\lib\config.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\FreeRadius\lib\dict.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\FreeRadius\lib\fr_log.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\FreeRadius\lib\fr_md5.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\FreeRadius\lib\fr_options.h</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\FreeRadius\lib\rc-md5.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\FreeRadius\lib\sendserver.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\FreeRadius\lib\util.c</name>
+        </file>
+      </group>
+    </group>
     <group>
       <name>freertos</name>
       <group>

+ 15 - 0
thirdparty/FreeRadius/include/Makefile.am

@@ -0,0 +1,15 @@
+# 
+#  $Id: Makefile.am,v 1.3 2007/01/06 20:15:28 pnixon Exp $
+# 
+#  Copyright (C) 1997 Lars Fenneberg
+# 
+#  See the file COPYRIGHT for the respective terms and conditions. 
+#  If the file is missing contact me at lf@elemental.net 
+#  and I'll send you a copy.
+# 
+#
+
+AUTOMAKE_OPTIONS = foreign
+
+noinst_HEADERS = pathnames.h messages.h includes.h
+include_HEADERS = freeradius-client.h

+ 572 - 0
thirdparty/FreeRadius/include/Makefile.in

@@ -0,0 +1,572 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# 
+#  $Id: Makefile.am,v 1.3 2007/01/06 20:15:28 pnixon Exp $
+# 
+#  Copyright (C) 1997 Lars Fenneberg
+# 
+#  See the file COPYRIGHT for the respective terms and conditions. 
+#  If the file is missing contact me at lf@elemental.net 
+#  and I'll send you a copy.
+# 
+#
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = include
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs $(include_HEADERS) \
+	$(noinst_HEADERS)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(includedir)"
+HEADERS = $(include_HEADERS) $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_CFLAGS = @CRYPTO_CFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBVERSION = @LIBVERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NETTLE_CFLAGS = @NETTLE_CFLAGS@
+NETTLE_LIBS = @NETTLE_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+RC_LOG_FACILITY = @RC_LOG_FACILITY@
+RC_SECURE_PATH = @RC_SECURE_PATH@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgsysconfdir = @pkgsysconfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = foreign
+noinst_HEADERS = pathnames.h messages.h includes.h
+include_HEADERS = freeradius-client.h
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign include/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-includeHEADERS: $(include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
+	done
+
+uninstall-includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(includedir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-includeHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-includeHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool cscopelist-am ctags ctags-am distclean \
+	distclean-generic distclean-libtool distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-includeHEADERS install-info install-info-am \
+	install-man install-pdf install-pdf-am install-ps \
+	install-ps-am install-strip installcheck installcheck-am \
+	installdirs maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+	ps ps-am tags tags-am uninstall uninstall-am \
+	uninstall-includeHEADERS
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:

+ 556 - 0
thirdparty/FreeRadius/include/freeradius-client.h

@@ -0,0 +1,556 @@
+/*
+ * $Id: freeradius-client.h,v 1.18 2010/06/15 09:22:51 aland Exp $
+ *
+ * Copyright (C) 1995,1996,1997,1998 Lars Fenneberg
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ *
+ * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
+ * and Merit Network, Inc. All Rights Reserved
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+#ifndef FREERADIUS_CLIENT_H
+#define FREERADIUS_CLIENT_H
+
+//#define CP_DEBUG
+
+#ifdef CP_DEBUG
+#define		DEBUG(args, ...)	rc_log(## args)
+#else
+#define		DEBUG(args, ...)	;
+#endif
+
+//#include	<sys/types.h>
+#include "radius_config.h"
+/*
+ * Include for C99 uintX_t defines is stdint.h on most systems.  Solaris uses
+ * inttypes.h instead.  Comment out the stdint include if you get an error,
+ * and uncomment the inttypes.h include.
+ */
+#include	<stdint.h>
+/* #include	<inttypes.h> */
+#include	<stdio.h>
+#include	<time.h>
+
+
+/* for struct addrinfo and sockaddr_storage */
+//#include <sys/socket.h>
+#include <netdb.h>
+
+#undef __BEGIN_DECLS
+#undef __END_DECLS
+#ifdef __cplusplus
+# define __BEGIN_DECLS extern "C" {
+# define __END_DECLS }
+#else
+# define __BEGIN_DECLS /* empty */
+# define __END_DECLS /* empty */
+#endif
+
+#define AUTH_VECTOR_LEN		16
+#define AUTH_PASS_LEN		(3 * 16) /* multiple of 16 */
+#define AUTH_ID_LEN		    64
+#define AUTH_STRING_LEN		253	 /* maximum of 253 */
+
+#define BUFFER_LEN		    8192
+
+#define NAME_LENGTH		    32
+#define GETSTR_LENGTH		128	//!< must be bigger than AUTH_PASS_LEN.
+
+#define MAX_SECRET_LENGTH	(3 * 16) /* MUST be multiple of 16 */
+
+#define VENDOR(x)		(((x) >> 16) & 0xffff)
+#define ATTRID(x)		((x) & 0xffff)
+
+#define PW_MAX_MSG_SIZE		256//4096
+
+   
+/* codes for radius_buildreq, radius_getport, etc. */
+#define AUTH			0
+#define ACCT			1
+
+/* defines for config.c */
+
+#define SERVER_MAX 8
+
+#define AUTH_LOCAL_FST	(1<<0)
+#define AUTH_RADIUS_FST	(1<<1)
+#define AUTH_LOCAL_SND	(1<<2)
+#define AUTH_RADIUS_SND	(1<<3)
+
+typedef struct server {
+	int max;
+	char *name[SERVER_MAX];
+	uint16_t port[SERVER_MAX];
+	char *secret[SERVER_MAX];
+	double deadtime_ends[SERVER_MAX];
+} SERVER;
+
+typedef struct pw_auth_hdr
+{
+	uint8_t		code;
+	uint8_t		id;
+	uint16_t	length;
+	uint8_t		vector[AUTH_VECTOR_LEN];
+	uint8_t		data[2];
+} AUTH_HDR;
+
+struct rc_conf
+{
+	struct _option		    *config_options;
+	struct sockaddr_storage	own_bind_addr;
+	unsigned		        own_bind_addr_set;
+
+	struct map2id_s		    *map2id_list;
+	struct dict_attr	    *dictionary_attributes;
+	struct dict_value	    *dictionary_values;
+	struct dict_vendor	    *dictionary_vendors;
+	char			        buf[GETSTR_LENGTH];
+    char    			    buf1[14];
+	char	    		    ifname[512];
+};
+
+typedef struct rc_conf rc_handle;
+
+#define AUTH_HDR_LEN			20
+#define CHAP_VALUE_LENGTH		16
+
+#define PW_AUTH_UDP_PORT		1645
+#define PW_ACCT_UDP_PORT		1646
+
+#define PW_TYPE_STRING			0
+#define PW_TYPE_INTEGER			1
+#define PW_TYPE_IPADDR			2
+#define PW_TYPE_DATE			3
+#define PW_TYPE_IPV6ADDR		4
+#define PW_TYPE_IPV6PREFIX		5
+
+/* standard RADIUS codes */
+
+#define PW_ACCESS_REQUEST		1
+#define PW_ACCESS_ACCEPT		2
+#define PW_ACCESS_REJECT		3
+#define PW_ACCOUNTING_REQUEST	4
+#define PW_ACCOUNTING_RESPONSE	5
+#define PW_ACCOUNTING_STATUS	6
+#define PW_PASSWORD_REQUEST		7
+#define PW_PASSWORD_ACK			8
+#define PW_PASSWORD_REJECT		9
+#define PW_ACCOUNTING_MESSAGE	10
+#define PW_ACCESS_CHALLENGE		11
+#define PW_STATUS_SERVER		12
+#define PW_STATUS_CLIENT		13
+
+
+/* standard RADIUS attribute-value pairs */
+
+#define PW_ACCESS               244
+
+#define PW_USER_NAME			1	//!< string.
+#define PW_USER_PASSWORD		2	//!< string.
+#define PW_CHAP_PASSWORD		3	//!< string.
+#define PW_NAS_IP_ADDRESS		4	//!< ipaddr.
+#define PW_NAS_PORT			    5	//!< integer.
+#define PW_SERVICE_TYPE			6	//!< integer.
+#define PW_FRAMED_PROTOCOL		7	//!< integer.
+#define PW_FRAMED_IP_ADDRESS	8	//!< ipaddr.
+#define PW_FRAMED_IP_NETMASK	9	//!< ipaddr.
+#define PW_FRAMED_ROUTING		10	//!< integer.
+#define PW_FILTER_ID			11	//!< string.
+#define PW_FRAMED_MTU			12	//!< integer.
+#define PW_FRAMED_COMPRESSION	13	//!< integer.
+#define PW_LOGIN_IP_HOST		14	//!< ipaddr.
+#define PW_LOGIN_SERVICE		15	//!< integer.
+#define PW_LOGIN_PORT			16	//!< integer.
+#define PW_OLD_PASSWORD			17	//!< string */ /* deprecated.
+#define PW_REPLY_MESSAGE		18	//!< string.
+#define PW_LOGIN_CALLBACK_NUMBER    19	//!< string.
+#define PW_FRAMED_CALLBACK_ID		20	//!< string.
+#define PW_EXPIRATION			21	//!< date */ /* deprecated.
+#define PW_FRAMED_ROUTE			22	//!< string.
+#define PW_FRAMED_IPX_NETWORK	23	//!< integer.
+#define PW_STATE			    24	//!< string.
+#define PW_CLASS			    25	//!< string.
+#define PW_VENDOR_SPECIFIC	    26	//!< string.
+#define PW_SESSION_TIMEOUT		27	//!< integer.
+#define PW_IDLE_TIMEOUT			28	//!< integer.
+#define PW_TERMINATION_ACTION	29	//!< integer.
+#define PW_CALLED_STATION_ID	30	//!< string.
+#define PW_CALLING_STATION_ID	31	//!< string.
+#define PW_NAS_IDENTIFIER		32	//!< string.
+#define PW_PROXY_STATE			33	//!< string.
+#define PW_LOGIN_LAT_SERVICE	34	//!< string.
+#define PW_LOGIN_LAT_NODE		35	//!< string.
+#define PW_LOGIN_LAT_GROUP		36	//!< string.
+#define PW_FRAMED_APPLETALK_LINK	37	//!< integer.
+#define PW_FRAMED_APPLETALK_NETWORK	38	//!< integer.
+#define PW_FRAMED_APPLETALK_ZONE	39	//!< string.
+#define PW_ACCT_STATUS_TYPE		    40	//!< integer.
+#define PW_ACCT_DELAY_TIME		    41	//!< integer.
+#define PW_ACCT_INPUT_OCTETS		42	//!< integer.
+#define PW_ACCT_OUTPUT_OCTETS		43	//!< integer.
+#define PW_ACCT_SESSION_ID		    44	//!< string.
+#define PW_ACCT_AUTHENTIC		    45	//!< integer.
+#define PW_ACCT_SESSION_TIME		46	//!< integer.
+#define PW_ACCT_INPUT_PACKETS		47	//!< integer.
+#define PW_ACCT_OUTPUT_PACKETS		48	//!< integer.
+#define PW_ACCT_TERMINATE_CAUSE		49	//!< integer.
+#define PW_ACCT_MULTI_SESSION_ID	50	//!< string.
+#define PW_ACCT_LINK_COUNT		    51	//!< integer.
+#define PW_ACCT_INPUT_GIGAWORDS		52	//!< integer.
+#define PW_ACCT_OUTPUT_GIGAWORDS	53	//!< integer.
+#define PW_EVENT_TIMESTAMP		    55	//!< integer.
+#define PW_EGRESS_VLANID		    56	//!< string.
+#define PW_INGRESS_FILTERS		    57	//!< integer.
+#define PW_EGRESS_VLAN_NAME		    58	//!< string.
+#define PW_USER_PRIORITY_TABLE		59	//!< string.
+#define PW_CHAP_CHALLENGE		    60	//!< string.
+#define PW_NAS_PORT_TYPE		    61	//!< integer.
+#define PW_PORT_LIMIT			    62	//!< integer.
+#define PW_LOGIN_LAT_PORT		    63	//!< string.
+#define PW_TUNNEL_TYPE			    64	//!< string.
+#define PW_TUNNEL_MEDIUM_TYPE		65	//!< integer.
+#define PW_TUNNEL_CLIENT_ENDPOINT	66	//!< string.
+#define PW_TUNNEL_SERVER_ENDPOINT	67	//!< string.
+#define PW_ACCT_TUNNEL_CONNECTION	68	//!< string.
+#define PW_TUNNEL_PASSWORD		    69	//!< string.
+#define PW_ARAP_PASSWORD		    70	//!< string.
+#define PW_ARAP_FEATURES		    71	//!< string.
+#define PW_ARAP_ZONE_ACCESS		    72	//!< integer.
+#define PW_ARAP_SECURITY		    73	//!< integer.
+#define PW_ARAP_SECURITY_DATA		74	//!< string.
+#define PW_PASSWORD_RETRY		    75	//!< integer.
+#define PW_PROMPT			        76	//!< integer.
+#define PW_CONNECT_INFO			    77	//!< string.
+#define PW_CONFIGURATION_TOKEN		78	//!< string.
+#define PW_EAP_MESSAGE			    79	//!< string.
+#define PW_MESSAGE_AUTHENTICATOR	80	//!< string.
+#define PW_TUNNEL_PRIVATE_GROUP_ID	81	//!< string.
+#define PW_TUNNEL_ASSIGNMENT_ID		82	//!< string.
+#define PW_TUNNEL_PREFERENCE		83	//!< string.
+#define PW_ARAP_CHALLENGE_RESPONSE	84	//!< string.
+#define PW_ACCT_INTERIM_INTERVAL	85	//!< integer.
+#define PW_ACCT_TUNNEL_PACKETS_LOST	86	//!< integer.
+#define PW_NAS_PORT_ID_STRING		87	//!< string.
+#define PW_FRAMED_POOL			    88	//!< string.
+#define PW_CHARGEABLE_USER_IDENTITY	89	//!< string.
+#define PW_CUI				        89	//!< string.
+#define PW_TUNNEL_CLIENT_AUTH_ID	90	//!< string.
+#define PW_TUNNEL_SERVER_AUTH_ID	91	//!< string.
+#define PW_NAS_FILTER_RULE		    92	//!< string.
+#define PW_ORIGINATING_LINE_INFO	94	//!< string.
+#define PW_NAS_IPV6_ADDRESS		    95	//!< string.
+#define PW_FRAMED_INTERFACE_ID		96	//!< string.
+#define PW_FRAMED_IPV6_PREFIX		97	//!< string.
+#define PW_LOGIN_IPV6_HOST		    98	//!< string.
+#define PW_FRAMED_IPV6_ROUTE		99	//!< string.
+#define PW_FRAMED_IPV6_POOL		    100	//!< string.
+#define PW_ERROR_CAUSE			    101	//!< integer.
+#define PW_EAP_KEY_NAME			    102	//!< string.
+
+#define PW_FRAMED_IPV6_ADDRESS		168	//!< ipaddr6.
+#define PW_DNS_SERVER_IPV6_ADDRESS	169	//!< ipaddr6.
+#define PW_ROUTE_IPV6_INFORMATION	170	//!< ipv6prefix.
+
+/* Experimental SIP-specific attributes (draft-sterman-aaa-sip-00.txt etc) */
+
+#define PW_DIGEST_RESPONSE		    206	//!< string.
+#define PW_DIGEST_ATTRIBUTES		207	//!< string.
+#define PW_DIGEST_REALM			    1063	//!< string.
+#define PW_DIGEST_NONCE			    1064	//!< string.
+#define PW_DIGEST_METHOD		    1065	//!< string.
+#define PW_DIGEST_URI			    1066	//!< string.
+#define PW_DIGEST_QOP			    1067	//!< string.
+#define PW_DIGEST_ALGORITHM		    1068	//!< string.
+#define PW_DIGEST_BODY_DIGEST		1069	//!< string.
+#define PW_DIGEST_CNONCE		    1070	//!< string.
+#define PW_DIGEST_NONCE_COUNT		1071	//!< string.
+#define PW_DIGEST_USER_NAME		    1072	//!< string.
+
+/* Integer Translations */
+
+/* SERVICE TYPES */
+
+#define PW_LOGIN			    1
+#define PW_FRAMED			    2
+#define PW_CALLBACK_LOGIN		3
+#define PW_CALLBACK_FRAMED		4
+#define PW_OUTBOUND			    5
+#define PW_ADMINISTRATIVE		6
+#define PW_NAS_PROMPT			7
+#define PW_AUTHENTICATE_ONLY	8
+#define PW_CALLBACK_NAS_PROMPT	9
+
+/* FRAMED PROTOCOLS */
+
+#define PW_PPP				1
+#define PW_SLIP				2
+#define PW_ARA				3
+#define PW_GANDALF			4
+#define PW_XYLOGICS			5
+
+/* FRAMED ROUTING VALUES */
+
+#define PW_NONE				0
+#define PW_BROADCAST		1
+#define PW_LISTEN			2
+#define PW_BROADCAST_LISTEN	3
+
+/* FRAMED COMPRESSION TYPES */
+
+#define PW_VAN_JACOBSON_TCP_IP		1
+#define PW_IPX_HEADER_COMPRESSION	2
+
+/* LOGIN SERVICES */
+
+#define PW_TELNET			0
+#define PW_RLOGIN			1
+#define PW_TCP_CLEAR		2
+#define PW_PORTMASTER		3
+#define PW_LAT				4
+#define PW_X25_PAD			5
+#define PW_X25_T3POS		6
+
+/* TERMINATION ACTIONS */
+
+#define PW_DEFAULT			0
+#define PW_RADIUS_REQUEST	1
+
+/* PROHIBIT PROTOCOL */
+
+#define PW_DUMB			    0	//!< 1 and 2 are defined in FRAMED PROTOCOLS.
+#define PW_AUTH_ONLY	    3
+#define PW_ALL			    255
+
+/* ACCOUNTING STATUS TYPES */
+
+#define PW_STATUS_START		1
+#define PW_STATUS_STOP		2
+#define PW_STATUS_ALIVE		3
+#define PW_STATUS_MODEM_START	4
+#define PW_STATUS_MODEM_STOP	5
+#define PW_STATUS_CANCEL	6
+#define PW_ACCOUNTING_ON	7
+#define PW_ACCOUNTING_OFF	8
+
+/* ACCOUNTING TERMINATION CAUSES */
+
+#define PW_USER_REQUEST		1
+#define PW_LOST_CARRIER		2
+#define PW_LOST_SERVICE		3
+#define PW_ACCT_IDLE_TIMEOUT	4
+#define PW_ACCT_SESSION_TIMEOUT	5
+#define PW_ADMIN_RESET		6
+#define PW_ADMIN_REBOOT		7
+#define PW_PORT_ERROR		8
+#define PW_NAS_ERROR		9
+#define PW_NAS_REQUEST		10
+#define PW_NAS_REBOOT		11
+#define PW_PORT_UNNEEDED	12
+#define PW_PORT_PREEMPTED	13
+#define PW_PORT_SUSPENDED	14
+#define PW_SERVICE_UNAVAILABLE	15
+#define PW_CALLBACK		    16
+#define PW_USER_ERROR		17
+#define PW_HOST_REQUEST		18
+
+/* NAS PORT TYPES */
+
+#define PW_ASYNC		    0
+#define PW_SYNC			    1
+#define PW_ISDN_SYNC		2
+#define PW_ISDN_SYNC_V120	3
+#define PW_ISDN_SYNC_V110	4
+#define PW_VIRTUAL		    5
+
+/* AUTHENTIC TYPES */
+
+#define PW_RADIUS	1
+#define PW_LOCAL	2
+#define PW_REMOTE	3
+
+/* Server data structures */
+
+typedef struct dict_attr
+{
+	char              name[NAME_LENGTH + 1];	//!< attribute name.
+	int               value;			//!< attribute index.
+	int               type;				//!< string, int, etc..
+	struct dict_attr *next;
+} DICT_ATTR;
+
+typedef struct dict_value
+{
+	char               attrname[NAME_LENGTH +1];
+	char               name[NAME_LENGTH + 1];
+	int                value;
+	struct dict_value *next;
+} DICT_VALUE;
+
+typedef struct dict_vendor
+{
+	char               vendorname[NAME_LENGTH +1];
+	int                vendorpec;
+	struct dict_vendor *next;
+} DICT_VENDOR;
+
+typedef struct value_pair
+{
+	char               name[NAME_LENGTH + 1];
+	int                attribute;
+	int                type;
+	uint32_t           lvalue;
+	char               strvalue[AUTH_STRING_LEN + 1];
+	struct value_pair *next;
+} VALUE_PAIR;
+
+/* Define return codes from "SendServer" utility */
+
+#define BADRESP_RC	-2
+#define ERROR_RC	-1
+#define OK_RC		0
+#define TIMEOUT_RC	1
+#define REJECT_RC	2
+
+typedef struct send_data /* Used to pass information to sendserver() function */
+{
+	uint8_t        code;		//!< RADIUS packet code.
+	uint8_t        seq_nbr;		//!< Packet sequence number.
+	char           *server;		//!< Name/addrress of RADIUS server.
+	int            svc_port;	//!< RADIUS protocol destination port.
+	char           *secret;		//!< Shared secret of RADIUS server.
+	int            timeout;		//!< Session timeout in seconds.
+	int            retries;
+	VALUE_PAIR     *send_pairs;     //!< More a/v pairs to send.
+	VALUE_PAIR     *receive_pairs;  //!< Where to place received a/v pairs.
+} SEND_DATA;
+
+#ifndef MIN
+#define MIN(a, b)     ((a) < (b) ? (a) : (b))
+#endif
+#ifndef MAX
+#define MAX(a, b)     ((a) > (b) ? (a) : (b))
+#endif
+
+#ifndef PATH_MAX
+#define PATH_MAX	1024
+#endif
+
+typedef struct env
+{
+	int maxsize, size;
+	char **env;
+} ENV;
+
+#define ENV_SIZE	128
+
+__BEGIN_DECLS
+
+/* Function prototypes */
+
+/* avpair.c */
+
+VALUE_PAIR *rc_avpair_add(rc_handle const *, VALUE_PAIR **, int, void const *, int, int);
+int rc_avpair_assign(VALUE_PAIR *, void const *, int);
+VALUE_PAIR *rc_avpair_new(rc_handle const *, int, void const *, int, int);
+VALUE_PAIR *rc_avpair_gen(rc_handle const *, VALUE_PAIR *, unsigned char const *, int, int);
+VALUE_PAIR *rc_avpair_get(VALUE_PAIR *, int, int);
+void rc_avpair_insert(VALUE_PAIR **, VALUE_PAIR *, VALUE_PAIR *);
+void rc_avpair_free(VALUE_PAIR *);
+int rc_avpair_parse(rc_handle const *, char const *, VALUE_PAIR **);
+int rc_avpair_tostr(rc_handle const *, VALUE_PAIR *, char *, int, char *, int);
+char *rc_avpair_log(rc_handle const *, VALUE_PAIR *, char *buf, size_t buf_len);
+VALUE_PAIR *rc_avpair_readin(rc_handle const *, FILE *);
+
+/* buildreq.c */
+
+void rc_buildreq(rc_handle const *, SEND_DATA *, int, char *, unsigned short, char *, int, int);
+unsigned char rc_get_id();
+int rc_auth(rc_handle *, uint32_t, VALUE_PAIR *, VALUE_PAIR **, char *);
+int rc_auth_proxy(rc_handle *, VALUE_PAIR *, VALUE_PAIR **, char *);
+int rc_acct(rc_handle *, uint32_t, VALUE_PAIR *);
+int rc_acct_proxy(rc_handle *, VALUE_PAIR *);
+int rc_check(rc_handle *, char *, char *, unsigned short, char *);
+
+int rc_aaa(rc_handle *rh, uint32_t client_port, VALUE_PAIR *send, VALUE_PAIR **received,
+    char *msg, int add_nas_port, int request_type);
+
+/* clientid.c */
+
+int rc_read_mapfile(rc_handle *, char const *);
+uint32_t rc_map2id(rc_handle const *, char const *);
+void rc_map2id_free(rc_handle *);
+
+/* config.c */
+
+//rc_handle *rc_read_config(char const *);
+void rc_read_config(rc_handle* rh);
+char *rc_conf_str(rc_handle const *, char const *);
+int rc_conf_int(rc_handle const *, char const *);
+SERVER *rc_conf_srv(rc_handle const *, char const *);
+void rc_config_free(rc_handle *);
+int rc_add_config(rc_handle *, char const *, char const *, char const *, int);
+rc_handle *rc_config_init(rc_handle *);
+int test_config(rc_handle const *, char const *);
+
+/* dict.c */
+
+int rc_read_dictionary(rc_handle *, char const *);
+DICT_ATTR *rc_dict_getattr(rc_handle const *, int);
+DICT_ATTR *rc_dict_findattr(rc_handle const *, char const *);
+DICT_VALUE *rc_dict_findval(rc_handle const *, char const *);
+DICT_VENDOR *rc_dict_findvend(rc_handle const *, char const *);
+DICT_VENDOR *rc_dict_getvend(rc_handle const *, int);
+DICT_VALUE * rc_dict_getval(rc_handle const *, uint32_t, char const *);
+void rc_dict_free(rc_handle *);
+
+/* ip_util.c */
+
+
+int rc_good_ipaddr(char const *);
+unsigned short rc_getport(int);
+int rc_own_hostname(char *, int);
+struct sockaddr;
+int rc_get_srcaddr(struct sockaddr *, const struct sockaddr *);
+
+
+/* log.c */
+
+void rc_openlog(char const *);
+void rc_log(int, char const *, ...);
+
+/* sendserver.c */
+
+int rc_send_server(rc_handle *, SEND_DATA *, char *, unsigned flags);
+
+/* util.c */
+
+void rc_str2tm(char const *, struct tm *);
+char *rc_getifname(rc_handle *, char const *);
+char *rc_getstr(rc_handle *, char const *, int);
+void rc_mdelay(int);
+char *rc_mksid(rc_handle *);
+rc_handle *rc_new(void);
+void rc_destroy(rc_handle *);
+char *rc_fgetln(FILE *, size_t *);
+double rc_getctime(void);
+
+/* env.c */
+
+struct env *rc_new_env(int);
+void rc_free_env(struct env *);
+int rc_add_env(struct env *, char const *, char const *);
+int rc_import_env(struct env *, char const **);
+
+/* md5.c */
+
+void rc_md5_calc(unsigned char *, unsigned char const *, unsigned int);
+
+__END_DECLS
+
+#endif /* FREERADIUS_CLIENT_H */

+ 188 - 0
thirdparty/FreeRadius/include/includes.h

@@ -0,0 +1,188 @@
+/*
+ * $Id: includes.h,v 1.6 2007/06/21 18:07:22 cparker Exp $
+ *
+ * Copyright (C) 1997 Lars Fenneberg
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ *
+ * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
+ * and Merit Network, Inc. All Rights Reserved
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+#ifndef RC_INCLUDES_H
+# define RC_INCLUDES_H
+
+#include "radius_config.h"
+#include "rtc.h"
+
+/* AIX requires this to be the first thing in the file.  */
+#ifndef __GNUC__
+# if HAVE_ALLOCA_H
+#  include <alloca.h>
+# else
+#  ifdef _AIX
+#   pragma alloca
+#  else
+#   ifndef alloca /* predefined by HP cc +Olibcalls */
+     char *alloca ();
+#   endif
+#  endif
+# endif
+#endif
+
+//#include <sys/types.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <errno.h>
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#ifdef HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <string.h>
+# include <stdarg.h>
+#else
+# include <stdarg.h>
+# ifndef HAVE_STRCHR
+#  define strchr index
+#  define strrchr rindex
+# endif
+#endif
+
+/* I realize that this is ugly and unsafe.. :( */
+#ifndef HAVE_SNPRINTF
+# define snprintf(buf, len, format, ...) sprintf(buf, format, __VA_ARGS__)
+#endif
+#ifndef HAVE_VSNPRINTF
+# define vsnprintf(buf, len, format, ap) vsprintf(buf, format, ap)
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#ifdef HAVE_SYS_FCNTL_H
+# include <sys/fcntl.h>
+#endif
+
+#ifdef HAVE_SYS_FILE_H
+# include <sys/file.h>
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#ifdef HAVE_SYS_UTSNAME_H
+# include <sys/utsname.h>
+#endif
+
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_CRYPT_H
+# include <crypt.h>
+#endif
+
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+#ifdef HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+#ifndef PATH_MAX
+#define PATH_MAX        1024
+#endif
+
+#ifndef UCHAR_MAX
+# ifdef  __STDC__
+#  define UCHAR_MAX       255U
+# else
+#  define UCHAR_MAX       255
+# endif
+#endif
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#if defined(HAVE_SIGNAL_H)
+# include <signal.h>
+#endif
+#if defined(HAVE_SYS_SIGNAL_H)
+# include <sys/signal.h>
+#endif
+
+#ifdef NEED_SIG_PROTOTYPES
+int sigemptyset(sigset_t *);
+int sigaddset(sigset_t *, int);
+int sigprocmask (int, sigset_t *, sigset_t *);
+#endif
+
+#if HAVE_GETOPT_H
+# include <getopt.h>
+#endif
+
+#if defined(HAVE_SHADOW_H) && defined(HAVE_SHADOW_PASSWORDS)
+# include <shadow.h>
+#endif
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+
+/*
+ * prefer srandom/random over srand/rand as there generator has a
+ * better distribution of the numbers on certain systems.
+ * on Linux both generators are identical.
+ */
+#ifndef HAVE_RANDOM
+# ifdef HAVE_RAND
+# define srandom        srand
+# define random         GetRandomNumber
+# endif
+#endif
+
+/* rlib/lock.c */
+int do_lock_exclusive(FILE *);
+int do_unlock(FILE *);
+
+#endif

+ 53 - 0
thirdparty/FreeRadius/include/messages.h

@@ -0,0 +1,53 @@
+/*
+ * $Id: messages.h,v 1.2 2004/02/23 20:10:39 sobomax Exp $
+ *
+ * Copyright (C) 1995,1996 Lars Fenneberg
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ *
+ * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
+ * and Merit Network, Inc. All Rights Reserved
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+/*
+ * Only messages that the user gets under normal use are in here.
+ * Error messages and such are still in the source code.
+ */
+
+#ifndef MESSAGES_H
+#define MESSAGES_H
+
+/* radlogin.c */
+
+#define SC_LOGIN	 "login: "
+#define SC_PASSWORD	 "Password: "
+
+#define SC_TIMEOUT	 "\r\nlogin timed out after %d seconds. Bye.\r\n"
+#define SC_EXCEEDED	 "Maximum login tries exceeded. Go away!\r\n"
+
+#define SC_RADIUS_OK	 "RADIUS: Authentication OK\r\n"
+#define SC_RADIUS_FAILED "RADIUS: Authentication failure\r\n"
+
+#define SC_LOCAL_OK	 "local: Authentication OK\r\n"
+#define SC_LOCAL_FAILED	 "local: Authentication failure\r\n"
+#define SC_NOLOGIN	 "\r\nSystem closed for maintenance. Try again later...\r\n"
+
+#define SC_SERVER_REPLY	 "RADIUS: %s"
+
+#define SC_DEFAULT_ISSUE "(\\I)\r\n\r\n\\S \\R (\\N) (port \\L)\r\n\r\n"
+
+/* radacct.c */
+
+#define SC_ACCT_OK	 "RADIUS accounting OK\r\n"
+#define SC_ACCT_FAILED	 "RADIUS accounting failed (RC=%i)\r\n"
+
+/* radstatus.c */
+
+#define SC_STATUS_FAILED	"RADIUS: Status failure\r\n"
+
+#endif /* MESSAGES_H */

+ 28 - 0
thirdparty/FreeRadius/include/pathnames.h

@@ -0,0 +1,28 @@
+/*
+ * $Id: pathnames.h,v 1.2 2004/02/23 20:10:39 sobomax Exp $
+ *
+ * Copyright (C) 1995,1996 Lars Fenneberg
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ *
+ * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
+ * and Merit Network, Inc. All Rights Reserved
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+#ifndef PATHNAMES_H
+#define PATHNAMES_H
+
+#define _PATH_DEV_URANDOM		"/dev/urandom"		/* Linux only */
+#define _PATH_ETC_ISSUE			"/etc/issue"
+
+/* normally defined in the Makefile */
+#ifndef _PATH_ETC_RADIUSCLIENT_CONF
+#  define _PATH_ETC_RADIUSCLIENT_CONF	"/etc/radiusclient.conf"
+#endif
+
+#endif /* PATHNAMES_H */

+ 32 - 0
thirdparty/FreeRadius/lib/Makefile.am

@@ -0,0 +1,32 @@
+#
+# $Id: Makefile.am,v 1.7 2010/02/04 10:27:09 aland Exp $
+#
+# Copyright (C) 1995,1997,1998 Lars Fenneberg
+#
+# See the file COPYRIGHT for the respective terms and conditions. 
+# If the file is missing contact me at lf@elemental.net 
+# and I'll send you a copy.
+#
+
+AUTOMAKE_OPTIONS = foreign
+
+RC_LOG_FACILITY = @RC_LOG_FACILITY@
+LIBVERSION = @LIBVERSION@
+
+AM_CPPFLAGS = -I$(srcdir) -I$(top_srcdir)/include -I$(top_builddir) $(CRYPTO_CFLAGS)
+DEFS = @DEFS@ -DRC_LOG_FACILITY=$(RC_LOG_FACILITY)
+
+CLEANFILES = *~
+
+lib_LTLIBRARIES =   libfreeradius-client.la
+libfreeradius_client_la_SOURCES = buildreq.c clientid.c env.c sendserver.c \
+	avpair.c config.c dict.c ip_util.c log.c util.c  \
+	options.h rc-md5.h rc-md5.c util.h
+
+if !ENABLE_NETTLE
+libfreeradius_client_la_SOURCES += md5.c md5.h
+endif
+
+libfreeradius_client_la_LDFLAGS = -version-info $(LIBVERSION)
+
+libfreeradius_client_la_LIBADD = $(CRYPTO_LIBS)

+ 682 - 0
thirdparty/FreeRadius/lib/Makefile.in

@@ -0,0 +1,682 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# $Id: Makefile.am,v 1.7 2010/02/04 10:27:09 aland Exp $
+#
+# Copyright (C) 1995,1997,1998 Lars Fenneberg
+#
+# See the file COPYRIGHT for the respective terms and conditions. 
+# If the file is missing contact me at lf@elemental.net 
+# and I'll send you a copy.
+#
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+@ENABLE_NETTLE_FALSE@am__append_1 = md5.c md5.h
+subdir = lib
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(libdir)"
+LTLIBRARIES = $(lib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libfreeradius_client_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am__libfreeradius_client_la_SOURCES_DIST = buildreq.c clientid.c env.c \
+	sendserver.c avpair.c config.c dict.c ip_util.c log.c util.c \
+	options.h rc-md5.h rc-md5.c md5.c md5.h
+@ENABLE_NETTLE_FALSE@am__objects_1 = md5.lo
+am_libfreeradius_client_la_OBJECTS = buildreq.lo clientid.lo env.lo \
+	sendserver.lo avpair.lo config.lo dict.lo ip_util.lo log.lo \
+	util.lo rc-md5.lo $(am__objects_1)
+libfreeradius_client_la_OBJECTS =  \
+	$(am_libfreeradius_client_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+libfreeradius_client_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(AM_CFLAGS) $(CFLAGS) $(libfreeradius_client_la_LDFLAGS) \
+	$(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+SOURCES = $(libfreeradius_client_la_SOURCES)
+DIST_SOURCES = $(am__libfreeradius_client_la_SOURCES_DIST)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_CFLAGS = @CRYPTO_CFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@ -DRC_LOG_FACILITY=$(RC_LOG_FACILITY)
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBVERSION = @LIBVERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NETTLE_CFLAGS = @NETTLE_CFLAGS@
+NETTLE_LIBS = @NETTLE_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+RC_LOG_FACILITY = @RC_LOG_FACILITY@
+RC_SECURE_PATH = @RC_SECURE_PATH@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgsysconfdir = @pkgsysconfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = foreign
+AM_CPPFLAGS = -I$(srcdir) -I$(top_srcdir)/include -I$(top_builddir) $(CRYPTO_CFLAGS)
+CLEANFILES = *~
+lib_LTLIBRARIES = libfreeradius-client.la
+libfreeradius_client_la_SOURCES = buildreq.c clientid.c env.c \
+	sendserver.c avpair.c config.c dict.c ip_util.c log.c util.c \
+	options.h rc-md5.h rc-md5.c $(am__append_1)
+libfreeradius_client_la_LDFLAGS = -version-info $(LIBVERSION)
+libfreeradius_client_la_LIBADD = $(CRYPTO_LIBS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign lib/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+	}
+
+uninstall-libLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+	done
+
+clean-libLTLIBRARIES:
+	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+	@list='$(lib_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libfreeradius-client.la: $(libfreeradius_client_la_OBJECTS) $(libfreeradius_client_la_DEPENDENCIES) $(EXTRA_libfreeradius_client_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(libfreeradius_client_la_LINK) -rpath $(libdir) $(libfreeradius_client_la_OBJECTS) $(libfreeradius_client_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/avpair.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buildreq.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clientid.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/config.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dict.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/env.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ip_util.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rc-md5.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sendserver.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+	for dir in "$(DESTDIR)$(libdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+	mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-libLTLIBRARIES
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-libLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \
+	ctags-am distclean distclean-compile distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-libLTLIBRARIES install-man install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:

+ 893 - 0
thirdparty/FreeRadius/lib/avpair.c

@@ -0,0 +1,893 @@
+/*
+ * $Id: avpair.c,v 1.26 2010/06/15 09:22:52 aland Exp $
+ *
+ * Copyright (C) 1995 Lars Fenneberg
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ *
+ * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
+ * and Merit Network, Inc. All Rights Reserved
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+#include <radius_config.h>
+#include <includes.h>
+#include <freeradius-client.h>
+#include "util.h"
+#include "def.h"
+
+/** Adds an attribute-value pair to the given list
+ *
+ * @note Always appends the new pair to the end of the list.
+ *
+ * @param rh a handle to parsed configuration.
+ * @param list a #VALUE_PAIR array of values; initially must be %NULL.
+ * @param attrid The attribute of the pair to add (e.g., %PW_USER_NAME).
+ * @param pval the value (e.g., the actual username).
+ * @param len the length of @pval, or -1 if to calculate (in case of strings).
+ * @param vendorpec The vendor ID in case of a vendor specific value - 0 otherwise.
+ * @return pointer to added a/v pair upon success, NULL pointer upon failure.
+ */
+VALUE_PAIR *rc_avpair_add (rc_handle const *rh, VALUE_PAIR **list, int attrid, void const *pval, int len, int vendorpec)
+{
+	VALUE_PAIR     *vp;
+
+	vp = rc_avpair_new (rh, attrid, pval, len, vendorpec);
+
+	if (vp != NULL)
+	{
+		rc_avpair_insert (list, NULL, vp);
+	}
+
+	return vp;
+}
+
+/** Assigns the given value to an attribute-value pair
+ *
+ * @param vp a pointer to a #VALUE_PAIR structure.
+ * @param pval the value (e.g., the actual username).
+ * @param len the length of @pval, or -1 if to calculate (in case of strings).
+ * @return 0 on success or -1 on failure.
+ */
+int rc_avpair_assign (VALUE_PAIR *vp, void const *pval, int len)
+{
+#if 1
+	switch (vp->type)
+	{
+		case PW_TYPE_STRING:
+			if (len == -1)
+				len = (uint32_t)strlen((char const *)pval);
+			if (len > AUTH_STRING_LEN) {
+		        	rc_log(LOG_ERR, "rc_avpair_assign: bad attribute length");
+		        	return -1;
+			}
+			memcpy(vp->strvalue, (char const *)pval, len);
+			vp->strvalue[len] = '\0';
+			vp->lvalue = len;
+			break;
+
+		case PW_TYPE_DATE:
+		case PW_TYPE_INTEGER:
+	        case PW_TYPE_IPADDR:
+			vp->lvalue = * (uint32_t *) pval;
+			break;
+	        case PW_TYPE_IPV6ADDR:
+			if (len != 16) {
+		        	rc_log(LOG_ERR, "rc_avpair_assign: bad IPv6 length");
+		        	return -1;
+			}
+			memcpy(vp->strvalue, (char const *)pval, len);
+			vp->lvalue = len;
+			break;
+
+	        case PW_TYPE_IPV6PREFIX:
+			if (len < 2 || len > 18) {
+		        	rc_log(LOG_ERR, "rc_avpair_assign: bad IPv6 prefix length");
+		        	return -1;
+			}
+			memcpy(vp->strvalue, (char const *)pval, len);
+			vp->lvalue = len;
+			break;
+
+		default:
+			rc_log(LOG_ERR, "rc_avpair_assign: unknown attribute %d", vp->type);
+			return -1;
+	}
+#endif    
+	return 0;
+}
+
+/** Make a new attribute-value pair with given parameters
+ *
+ * @param rh a handle to parsed configuration.
+ * @param attrid The attribute of the pair to add (e.g., %PW_USER_NAME).
+ * @param pval the value (e.g., the actual username).
+ * @param len the length of pval, or -1 if to calculate (in case of strings).
+ * @param vendorpec The vendor ID in case of a vendor specific value - 0 otherwise.
+ * @return pointer to generated a/v pair when successful, NULL when failure.
+ */
+VALUE_PAIR *rc_avpair_new (rc_handle const *rh, int attrid, void const *pval, int len, int vendorpec)
+{
+ 
+	VALUE_PAIR     *vp = NULL;
+	DICT_ATTR      *pda;
+
+	attrid = attrid | (vendorpec << 16);
+	if ((pda = rc_dict_getattr (rh, attrid)) == NULL)
+	{
+		rc_log(LOG_ERR,"rc_avpair_new: unknown attribute %d", attrid);
+		return NULL;
+	}
+	if (vendorpec != 0 && rc_dict_getvend(rh, vendorpec) == NULL)
+	{
+		rc_log(LOG_ERR,"rc_avpair_new: unknown Vendor-Id %d", vendorpec);
+		return NULL;
+	}
+	if ((vp = malloc (sizeof (VALUE_PAIR))) != NULL)
+	{
+		strlcpy (vp->name, pda->name, sizeof (vp->name));
+		vp->attribute = attrid;
+		vp->next = NULL;
+		vp->type = pda->type;
+		if (rc_avpair_assign (vp, pval, len) == 0)
+		{
+			/* XXX: Fix up Digest-Attributes */
+			switch (vp->attribute) {
+			case PW_DIGEST_REALM:
+			case PW_DIGEST_NONCE:
+			case PW_DIGEST_METHOD:
+			case PW_DIGEST_URI:
+			case PW_DIGEST_QOP:
+			case PW_DIGEST_ALGORITHM:
+			case PW_DIGEST_BODY_DIGEST:
+			case PW_DIGEST_CNONCE:
+			case PW_DIGEST_NONCE_COUNT:
+			case PW_DIGEST_USER_NAME:
+				/* overlapping! */
+				if (vp->lvalue > AUTH_STRING_LEN - 2)
+					vp->lvalue = AUTH_STRING_LEN - 2;
+				memmove(&vp->strvalue[2], &vp->strvalue[0], vp->lvalue);
+				vp->strvalue[0] = vp->attribute - PW_DIGEST_REALM + 1;
+				vp->lvalue += 2;
+				vp->strvalue[1] = vp->lvalue;
+				vp->strvalue[vp->lvalue] = '\0';
+				vp->attribute = PW_DIGEST_ATTRIBUTES;
+			default:
+				break;
+			}
+			return vp;
+		}
+		free (vp);
+		vp = NULL;
+	}
+	else
+	{
+		rc_log(LOG_CRIT,"rc_avpair_new: out of memory");
+	}
+
+	return vp;
+}
+
+/** Takes attribute/value pairs from buffer and builds a value_pair list using allocated memory
+ *
+ * @note Uses recursion.
+ *
+ * @param rh a handle to parsed configuration.
+ * @param pair a pointer to a #VALUE_PAIR structure.
+ * @param ptr the value (e.g., the actual username).
+ * @param length the length of ptr, or -1 if to calculate (in case of strings).
+ * @param vendorpec The vendor ID in case of a vendor specific value - 0 otherwise.
+ * @return value_pair list or %NULL on failure.
+ */
+VALUE_PAIR *rc_avpair_gen(rc_handle const *rh, VALUE_PAIR *pair, unsigned char const *ptr,
+			  int length, int vendorpec)
+{
+#if 1
+	int attribute, attrlen, x_len;
+	unsigned char const *x_ptr;
+	uint32_t lvalue;
+	DICT_ATTR *attr;
+	VALUE_PAIR *rpair;
+	char buffer[(AUTH_STRING_LEN * 2) + 1];
+	/* For hex string conversion. */
+	char hex[3];
+
+	if (length < 2) {
+		rc_log(LOG_ERR, "rc_avpair_gen: received attribute with "
+		    "invalid length");
+		goto shithappens;
+	}
+	attrlen = ptr[1];
+	if (length < attrlen || attrlen < 2) {
+		rc_log(LOG_ERR, "rc_avpair_gen: received attribute with "
+		    "invalid length");
+		goto shithappens;
+	}
+
+	/* Advance to the next attribute and process recursively */
+	if (length != attrlen) {
+		pair = rc_avpair_gen(rh, pair, ptr + attrlen, length - attrlen,
+		    vendorpec);
+		if (pair == NULL)
+			return NULL;
+	}
+
+	/* Actual processing */
+	attribute = ptr[0] | (vendorpec << 16);
+	ptr += 2;
+	attrlen -= 2;
+
+	/* VSA */
+	if (attribute == PW_VENDOR_SPECIFIC) {
+		if (attrlen < 4) {
+			rc_log(LOG_ERR, "rc_avpair_gen: received VSA "
+			    "attribute with invalid length");
+			goto skipit;
+		}
+		memcpy(&lvalue, ptr, 4);
+		vendorpec = ntohl(lvalue);
+		if (rc_dict_getvend(rh, vendorpec) == NULL) {
+			/* Warn and skip over the unknown VSA */
+			rc_log(LOG_WARNING, "rc_avpair_gen: received VSA "
+			    "attribute with unknown Vendor-Id %d", vendorpec);
+			goto skipit;
+		}
+		/* Process recursively */
+		return rc_avpair_gen(rh, pair, ptr + 4, attrlen - 4,
+		    vendorpec);
+	}
+
+	/* Normal */
+	attr = rc_dict_getattr(rh, attribute);
+	if (attr == NULL) {
+		buffer[0] = '\0';	/* Initial length. */
+		x_ptr = ptr;
+		for (x_len = attrlen; x_len > 0; x_len--, x_ptr++) {
+			snprintf(hex, sizeof(hex), "%2.2X", x_ptr[0]);
+			strcat(buffer, hex);
+		}
+		if (vendorpec == 0) {
+			rc_log(LOG_WARNING, "rc_avpair_gen: received "
+			    "unknown attribute %d of length %d: 0x%s",
+			    attribute, attrlen + 2, buffer);
+		} else {
+			rc_log(LOG_WARNING, "rc_avpair_gen: received "
+			    "unknown VSA attribute %d, vendor %d of "
+			    "length %d: 0x%s", attribute & 0xffff,
+			    VENDOR(attribute), attrlen + 2, buffer);
+		}
+		goto skipit;
+	}
+
+	rpair = malloc(sizeof(*rpair));
+	if (rpair == NULL) {
+		rc_log(LOG_CRIT, "rc_avpair_gen: out of memory");
+		goto shithappens;
+	}
+	memset(rpair, '\0', sizeof(*rpair));
+
+	/* Insert this new pair at the beginning of the list */
+	rpair->next = pair;
+	pair = rpair;
+	strcpy(pair->name, attr->name);
+	pair->attribute = attr->value;
+	pair->type = attr->type;
+
+	switch (attr->type) {
+	case PW_TYPE_STRING:
+		memcpy(pair->strvalue, (char *)ptr, (size_t)attrlen);
+		pair->strvalue[attrlen] = '\0';
+		pair->lvalue = attrlen;
+		break;
+
+	case PW_TYPE_INTEGER:
+		if (attrlen != 4) {
+			rc_log(LOG_ERR, "rc_avpair_gen: received INT "
+			    "attribute with invalid length");
+			goto skipit;
+		}
+	case PW_TYPE_IPADDR:
+		if (attrlen != 4) {
+			rc_log(LOG_ERR, "rc_avpair_gen: received IPADDR"
+			    " attribute with invalid length");
+			goto skipit;
+		}
+		memcpy((char *)&lvalue, (char *)ptr, 4);
+		pair->lvalue = ntohl(lvalue);
+		break;
+	case PW_TYPE_IPV6ADDR:
+		if (attrlen != 16) {
+			rc_log(LOG_ERR, "rc_avpair_gen: received IPV6ADDR"
+			    " attribute with invalid length");
+			goto skipit;
+		}
+		memcpy(pair->strvalue, (char *)ptr, 16);
+		pair->lvalue = attrlen;
+		break;
+	case PW_TYPE_IPV6PREFIX:
+		if (attrlen > 18 || attrlen < 2) {
+			rc_log(LOG_ERR, "rc_avpair_gen: received IPV6PREFIX"
+			    " attribute with invalid length: %d", attrlen);
+			goto skipit;
+		}
+		memcpy(pair->strvalue, (char *)ptr, attrlen);
+		pair->lvalue = attrlen;
+		break;
+	case PW_TYPE_DATE:
+		if (attrlen != 4) {
+			rc_log(LOG_ERR, "rc_avpair_gen: received DATE "
+			    "attribute with invalid length");
+			goto skipit;
+		}
+
+	default:
+		rc_log(LOG_WARNING, "rc_avpair_gen: %s has unknown type",
+		    attr->name);
+		goto skipit;
+	}
+
+skipit:
+	return pair;
+
+shithappens:
+	while (pair != NULL) {
+		rpair = pair->next;
+		free(pair);
+		pair = rpair;
+	}
+#endif    
+	return NULL;
+}
+
+/** Find the first attribute value-pair (which matches the given attribute) from the specified value-pair list
+ *
+ * @param vp a pointer to a #VALUE_PAIR structure.
+ * @param attrid The attribute of the pair to find (e.g., %PW_USER_NAME).
+ * @param vendorpec The vendor ID in case of a vendor specific value - 0 otherwise.
+ * @return the value pair found.
+ */
+VALUE_PAIR *rc_avpair_get (VALUE_PAIR *vp, int attrid, int vendorpec)
+{
+	for (; vp != NULL && !(ATTRID(vp->attribute) == ATTRID(attrid) &&
+	    VENDOR(vp->attribute) == vendorpec); vp = vp->next)
+	{
+		continue;
+	}
+  
+	return vp;
+}
+
+/** Insert a VALUE_PAIR into a list
+ *
+ * Given the address of an existing list "a" and a pointer to an entry "p" in that list, add the value pair "b" to
+ * the "a" list after the "p" entry.  If "p" is NULL, add the value pair "b" to the end of "a".
+ *
+ * @param a a #VALUE_PAIR array of values.
+ * @param p a pointer to a #VALUE_PAIR in a.
+ * @param b The #VALUE_PAIR pointer to add in a.
+ */
+void rc_avpair_insert(VALUE_PAIR **a, VALUE_PAIR *p, VALUE_PAIR *b)
+{
+	VALUE_PAIR     *this_node = NULL;
+	VALUE_PAIR     *vp;
+
+	if (b->next != NULL)
+	{
+		rc_log(LOG_CRIT, "rc_avpair_insert: value pair (0x%p) next ptr. (0x%p) not NULL", b, b->next);
+		abort ();
+	}
+
+	if (*a == NULL)
+	{
+		*a = b;
+		return;
+	}
+
+	vp = *a;
+
+	if ( p == NULL) /* run to end of "a" list */
+	{
+		while (vp != NULL)
+		{
+			this_node = vp;
+			vp = vp->next;
+		}
+	}
+	else /* look for the "p" entry in the "a" list */
+	{
+		this_node = *a;
+		while (this_node != NULL)
+		{
+			if (this_node == p)
+			{
+				break;
+			}
+			this_node = this_node->next;
+		}
+	}
+
+	b->next = this_node->next;
+	this_node->next = b;
+
+	return;
+}
+
+/** Frees all value_pairs in the list
+ *
+ * @param pair a pointer to a VALUE_PAIR structure.
+ */
+void rc_avpair_free (VALUE_PAIR *pair)
+{
+#if 0  
+	VALUE_PAIR     *next;
+
+	while (pair != NULL)
+	{
+		next = pair->next;
+		free (pair);
+		pair = next;
+	}
+#endif    
+}
+
+/** Copy a data field from the buffer
+ *
+ * Advance the buffer past the data field. Ensure that no more than len - 1 bytes are copied and that resulting
+ * string is terminated with '\0'.
+ *
+ * @param string the provided string to copy.
+ * @param uptr the current position of the buffer.
+ * @param stopat characters to which parsing should stop.
+ * @param len the maximum length of string.
+ */
+static void rc_fieldcpy(char *string, char const **uptr, char const *stopat, size_t len)
+{
+#if 0  
+	char const *ptr, *estring;
+
+	ptr = *uptr;
+	estring = string + len - 1;
+	if (*ptr == '"')
+	{
+		ptr++;
+		while (*ptr != '"' && *ptr != '\0' && *ptr != '\n')
+		{
+			if (string < estring)
+				*string++ = *ptr;
+			ptr++;
+		}
+		if (*ptr == '"')
+		{
+			ptr++;
+		}
+		*string = '\0';
+		*uptr = ptr;
+		return;
+	}
+
+	while (*ptr != '\0' && strchr(stopat, *ptr) == NULL)
+	{
+		if (string < estring)
+			*string++ = *ptr;
+		ptr++;
+	}
+	*string = '\0';
+	*uptr = ptr;
+#endif
+	return;
+}
+
+#define PARSE_MODE_NAME		0
+#define PARSE_MODE_EQUAL	1
+#define PARSE_MODE_VALUE	2
+#define PARSE_MODE_INVALID	3
+
+/** Parses the buffer to extract the attribute-value pairs
+ *
+ * @param rh a handle to parsed configuration.
+ * @param buffer the buffer to be parsed.
+ * @param first_pair an allocated array of values.
+ * @return 0 on successful parse of attribute-value pair, or -1 on syntax (or other) error detected.
+ */
+int rc_avpair_parse (rc_handle const *rh, char const *buffer, VALUE_PAIR **first_pair)
+{
+#if 0  
+	int             mode;
+	char            attrstr[AUTH_ID_LEN];
+	char            valstr[AUTH_STRING_LEN + 1], *p;
+	DICT_ATTR      *attr = NULL;
+	DICT_VALUE     *dval;
+	VALUE_PAIR     *pair;
+	VALUE_PAIR     *link;
+	struct tm      *tm;
+	time_t          timeval;
+
+	mode = PARSE_MODE_NAME;
+	while (*buffer != '\n' && *buffer != '\0')
+	{
+		if (*buffer == ' ' || *buffer == '\t')
+		{
+			buffer++;
+			continue;
+		}
+
+		switch (mode)
+		{
+		    case PARSE_MODE_NAME:		/* Attribute Name */
+			rc_fieldcpy (attrstr, &buffer, " \t\n=,", sizeof(attrstr));
+			if ((attr =
+				rc_dict_findattr (rh, attrstr)) == NULL)
+			{
+				rc_log(LOG_ERR, "rc_avpair_parse: unknown attribute");
+				if (*first_pair) {
+					rc_avpair_free(*first_pair);
+					*first_pair = NULL;
+				}
+				return -1;
+			}
+			mode = PARSE_MODE_EQUAL;
+			break;
+
+		    case PARSE_MODE_EQUAL:		/* Equal sign */
+			if (*buffer == '=')
+			{
+				mode = PARSE_MODE_VALUE;
+				buffer++;
+			}
+			else
+			{
+				rc_log(LOG_ERR, "rc_avpair_parse: missing or misplaced equal sign");
+				if (*first_pair) {
+					rc_avpair_free(*first_pair);
+					*first_pair = NULL;
+				}
+				return -1;
+			}
+			break;
+
+		    case PARSE_MODE_VALUE:		/* Value */
+			rc_fieldcpy (valstr, &buffer, " \t\n,", sizeof(valstr));
+
+			if ((pair = malloc (sizeof (VALUE_PAIR))) == NULL)
+			{
+				rc_log(LOG_CRIT, "rc_avpair_parse: out of memory");
+				if (*first_pair) {
+					rc_avpair_free(*first_pair);
+					*first_pair = NULL;
+				}
+				return -1;
+			}
+			strcpy (pair->name, attr->name);
+			pair->attribute = attr->value;
+			pair->type = attr->type;
+
+			switch (pair->type)
+			{
+
+			    case PW_TYPE_STRING:
+				strcpy (pair->strvalue, valstr);
+				pair->lvalue = (uint32_t)strlen(valstr);
+				break;
+
+			    case PW_TYPE_INTEGER:
+				if (isdigit (*valstr))
+				{
+					pair->lvalue = atoi (valstr);
+				}
+				else
+				{
+					if ((dval = rc_dict_findval (rh, valstr))
+							== NULL)
+					{
+						rc_log(LOG_ERR, "rc_avpair_parse: unknown attribute value: %s", valstr);
+						if (*first_pair) {
+							rc_avpair_free(*first_pair);
+							*first_pair = NULL;
+						}
+						free (pair);
+						return -1;
+					}
+					else
+					{
+						pair->lvalue = dval->value;
+					}
+				}
+				break;
+
+			    case PW_TYPE_IPADDR:
+			    	if (inet_pton(AF_INET, valstr, &pair->lvalue) == 0) {
+			    		rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv4 address %s", valstr);
+			    		free(pair);
+			    		return -1;
+			    	}
+
+                                pair->lvalue = ntohl(pair->lvalue);
+				break;
+
+			    case PW_TYPE_IPV6ADDR:
+			    	if (inet_pton(AF_INET6, valstr, pair->strvalue) == 0) {
+			    		rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv6 address %s", valstr);
+			    		free(pair);
+			    		return -1;
+			    	}
+				pair->lvalue = 16;
+				break;
+
+			    case PW_TYPE_IPV6PREFIX:
+			    	p = strchr(valstr, '/');
+			    	if (p == NULL) {
+			    		rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv6 prefix %s", valstr);
+			    		free(pair);
+			    		return -1;
+			    	}
+			    	*p = 0;
+			    	p++;
+			    	pair->strvalue[0] = 0;
+			    	pair->strvalue[1] = atoi(p);
+
+			    	if (inet_pton(AF_INET6, valstr, pair->strvalue+2) == 0) {
+			    		rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv6 prefix %s", valstr);
+			    		free(pair);
+			    		return -1;
+			    	}
+				pair->lvalue = 2+16;
+				break;
+
+			    case PW_TYPE_DATE:
+				timeval = time (0);
+				tm = localtime (&timeval);
+				tm->tm_hour = 0;
+				tm->tm_min = 0;
+				tm->tm_sec = 0;
+				rc_str2tm (valstr, tm);
+#ifdef TIMELOCAL
+				pair->lvalue = (uint32_t) timelocal (tm);
+#else	/* TIMELOCAL */
+				pair->lvalue = (uint32_t) mktime (tm);
+#endif	/* TIMELOCAL */
+				break;
+
+			    default:
+				rc_log(LOG_ERR, "rc_avpair_parse: unknown attribute type %d", pair->type);
+				if (*first_pair) {
+					rc_avpair_free(*first_pair);
+					*first_pair = NULL;
+				}
+				free (pair);
+				return -1;
+			}
+
+			/* XXX: Fix up Digest-Attributes */
+			switch (pair->attribute) {
+			case PW_DIGEST_REALM:
+			case PW_DIGEST_NONCE:
+			case PW_DIGEST_METHOD:
+			case PW_DIGEST_URI:
+			case PW_DIGEST_QOP:
+			case PW_DIGEST_ALGORITHM:
+			case PW_DIGEST_BODY_DIGEST:
+			case PW_DIGEST_CNONCE:
+			case PW_DIGEST_NONCE_COUNT:
+			case PW_DIGEST_USER_NAME:
+				/* overlapping! */
+				if (pair->lvalue > AUTH_STRING_LEN - 2)
+					pair->lvalue = AUTH_STRING_LEN - 2;
+				memmove(&pair->strvalue[2], &pair->strvalue[0], pair->lvalue);
+				pair->strvalue[0] = pair->attribute - PW_DIGEST_REALM + 1;
+				pair->lvalue += 2;
+				pair->strvalue[1] = pair->lvalue;
+				pair->strvalue[pair->lvalue] = '\0';
+				pair->attribute = PW_DIGEST_ATTRIBUTES;
+			}
+
+			pair->next = NULL;
+
+			if (*first_pair == NULL)
+			{
+				*first_pair = pair;
+			}
+			else
+			{
+				link = *first_pair;
+				while (link->next != NULL)
+				{
+					link = link->next;
+				}
+				link->next = pair;
+			}
+
+			mode = PARSE_MODE_NAME;
+			break;
+
+		    default:
+			mode = PARSE_MODE_NAME;
+			break;
+		}
+	}
+#endif
+	return 0;
+}
+
+/** Translate an av_pair into two strings
+ *
+ * @param rh a handle to parsed configuration.
+ * @param pair a pointer to a VALUE_PAIR structure.
+ * @param name the name of the pair.
+ * @param ln the size of name.
+ * @param value the value of the pair.
+ * @param lv the size of value.
+ * @return 0 on success, -1 on failure.
+ */
+int rc_avpair_tostr (rc_handle const *rh, VALUE_PAIR *pair, char *name, int ln, char *value, int lv)
+{
+#if 0  
+	DICT_VALUE     *dval;
+	char            buffer[32];
+	struct in_addr  inad;
+	unsigned char  *ptr;
+	unsigned int    pos;
+
+	*name = *value = '\0';
+
+	if (!pair || pair->name[0] == '\0') {
+		rc_log(LOG_ERR, "rc_avpair_tostr: pair is NULL or empty");
+		return -1;
+	}
+
+	strlcpy(name, pair->name, (size_t) ln);
+
+	switch (pair->type)
+	{
+	    case PW_TYPE_STRING:
+	    	lv--;
+	    	pos = 0;
+		ptr = (unsigned char *) pair->strvalue;
+		if (pair->attribute == PW_DIGEST_ATTRIBUTES) {
+			pair->strvalue[*(ptr + 1)] = '\0';
+			ptr += 2;
+		}
+		while (*ptr != '\0')
+		{
+			if (!(isprint (*ptr)))
+			{
+				if (lv >= 4) {
+					snprintf (&value[pos], lv, "\\%03o", *ptr);
+					pos += 4;
+					lv -= 4;
+				} else {
+					break;
+				}
+			}
+			else
+			{
+				if (lv > 0) {
+					value[pos++] = *ptr;
+					lv--;
+				} else {
+					break;
+				}
+			}
+			ptr++;
+		}
+		if (lv > 0)
+			value[pos++] = 0;
+		else
+			value[pos-1] = 0;
+		break;
+
+	    case PW_TYPE_INTEGER:
+		dval = rc_dict_getval (rh, pair->lvalue, pair->name);
+		if (dval != NULL)
+		{
+			strlcpy(value, dval->name, (size_t) lv);
+		}
+		else
+		{
+			snprintf(value, lv, "%ld", (long int)pair->lvalue);
+		}
+		break;
+
+	    case PW_TYPE_IPADDR:
+		inad.s_addr = htonl(pair->lvalue);
+		strlcpy (value, inet_ntoa (inad), (size_t) lv);
+		break;
+
+	    case PW_TYPE_IPV6ADDR:
+	    	if (inet_ntop(AF_INET6, pair->strvalue, value, lv) == NULL)
+	    		return -1;
+		break;
+
+	    case PW_TYPE_IPV6PREFIX: {
+	    	uint8_t ip[16];
+	    	char txt[48];
+	    	if (pair->lvalue < 2)
+	    		return -1;
+
+	    	memset(ip, 0, sizeof(ip));
+	    	memcpy(ip, pair->strvalue+2, pair->lvalue-2);
+
+	    	if (inet_ntop(AF_INET6, ip, txt, sizeof(txt)) == NULL)
+	    		return -1;
+		snprintf(value, lv, "%s/%u", txt, (unsigned)pair->strvalue[1]);
+
+		break;
+	    }
+	    case PW_TYPE_DATE:
+		strftime (value, lv, "%m/%d/%y %H:%M:%S",
+			  gmtime ((time_t *) & pair->lvalue));
+		break;
+
+	    default:
+		rc_log(LOG_ERR, "rc_avpair_tostr: unknown attribute type %d", pair->type);
+		return -1;
+		break;
+	}
+#endif
+	return 0;
+}
+
+/** Format a sequence of attribute value pairs into a printable string
+ *
+ * The caller should provide a storage buffer and the buffer length.
+ *
+ * @param rh a handle to parsed configuration.
+ * @param pair a pointer to a #VALUE_PAIR structure.
+ * @param buf will hold the string output of the pair.
+ * @param len the size of buf.
+ * @return a pointer to provided storage buffer.
+ */
+char *rc_avpair_log(rc_handle const *rh, VALUE_PAIR *pair, char *buf, size_t buf_len)
+{
+#if 0  
+	size_t len, nlen;
+	VALUE_PAIR *vp;
+	char name[33], value[256];
+
+	len = 0;
+	for (vp = pair; vp != NULL; vp = vp->next) {
+		if (rc_avpair_tostr(rh, vp, name, sizeof(name), value,
+		    sizeof(value)) == -1)
+		        return NULL;
+		nlen = len + 32 + 3 + strlen(value) + 2 + 2;
+		if(nlen<buf_len-1) {
+			sprintf(buf + len, "%-32s = '%s'\n", name, value);
+		} else return buf;
+		len = nlen - 1;
+	}
+#endif    
+	return buf;
+}
+
+/** Get a sequence of attribute value pairs from the file input and make them into a list of value_pairs
+ *
+ * @param rh a handle to parsed configuration.
+ * @param input a %FILE handle.
+ * @return the array of value pairs.
+ */
+VALUE_PAIR *rc_avpair_readin(rc_handle const *rh, FILE *input)
+{
+	VALUE_PAIR *vp = NULL;
+#if 0  
+	char buffer[1024], *q;
+
+	while (fgets(buffer, sizeof(buffer), input) != NULL)
+	{
+		q = buffer;
+
+		while(*q && isspace(*q)) q++;
+
+		if ((*q == '\n') || (*q == '#') || (*q == '\0'))
+			continue;
+
+		if (rc_avpair_parse(rh, q, &vp) < 0) {
+			rc_log(LOG_ERR, "rc_avpair_readin: malformed attribute: %s", buffer);
+			rc_avpair_free(vp);
+			return NULL;
+		}
+	}
+#endif
+	return vp;
+}

+ 392 - 0
thirdparty/FreeRadius/lib/buildreq.c

@@ -0,0 +1,392 @@
+/*
+ * $Id: buildreq.c,v 1.17 2010/02/04 10:27:09 aland Exp $
+ *
+ * Copyright (C) 1995,1997 Lars Fenneberg
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+#include <radius_config.h>
+#include <includes.h>
+#include <freeradius-client.h>
+#include "util.h"
+
+/** Build a skeleton RADIUS request using information from the config file
+ *
+ * @param rh a handle to parsed configuration.
+ * @param data a pointer to a #SEND_DATA structure.
+ * @param code one of standard RADIUS codes (e.g., %PW_ACCESS_REQUEST).
+ * @param server the name of the server.
+ * @param port the server's port number.
+ * @param secret the secret used by the server.
+ * @param timeout the timeout in seconds of a message.
+ * @param retries the number of retries.
+ */
+void rc_buildreq(rc_handle const *rh, SEND_DATA *data, int code, char *server, unsigned short port,
+		 char *secret, int timeout, int retries)
+{
+	data->server = server;
+	data->secret = secret;
+	data->svc_port = port;
+	data->seq_nbr = rc_get_id();
+	data->timeout = timeout;
+	data->retries = retries;
+	data->code = code;
+}
+
+/** Generates a random ID
+ *
+ * @return the random ID.
+ */
+unsigned char rc_get_id()
+{
+	return (unsigned char)(random() & UCHAR_MAX);
+}
+
+/** Builds an authentication/accounting request for port id client_port with the value_pairs send and submits it to a server
+ *
+ * @param rh a handle to parsed configuration.
+ * @param client_port the client port number to use (may be zero to use any available).
+ * @param send a #VALUE_PAIR array of values (e.g., %PW_USER_NAME).
+ * @param received an allocated array of received values.
+ * @param msg must be an array of %PW_MAX_MSG_SIZE or %NULL; will contain the concatenation of any
+ *	%PW_REPLY_MESSAGE received.
+ * @param add_nas_port if non-zero it will include %PW_NAS_PORT in sent pairs.
+ * @param request_type one of standard RADIUS codes (e.g., %PW_ACCESS_REQUEST).
+ * @return received value_pairs in received, messages from the server in msg and %OK_RC (0) on success, negative
+ *	on failure as return value.
+ */
+int rc_aaa(rc_handle *rh, uint32_t client_port, VALUE_PAIR *send, VALUE_PAIR **received,
+	   char *msg, int add_nas_port, int request_type)
+{
+	SEND_DATA   data;
+	VALUE_PAIR	*adt_vp = NULL;
+	int		    result;
+	int		    i, skip_count;
+	SERVER		*aaaserver;
+	int		    timeout = rc_conf_int(rh, "radius_timeout");
+	int		    retries = rc_conf_int(rh, "radius_retries");
+	int		    radius_deadtime = rc_conf_int(rh, "radius_deadtime");
+	double		start_time = 0;
+	double		now = 0;
+	time_t		dtime;
+	unsigned	type;
+
+// -----------------------------------------------------------------------------
+// Мои дополнения    
+
+    SERVER myServer;
+    char   myServerName[NAME_LENGTH] = "192.168.14.234";  
+    char   mySecret[MAX_SECRET_LENGTH] = "12345";
+    
+    myServer.max = 1;
+    myServer.name[0] = myServerName;
+    myServer.port[0] = 1645;
+    myServer.secret[0] = mySecret;
+    myServer.deadtime_ends[0] = 5000;
+    
+    aaaserver = &myServer;
+    type = AUTH;
+    
+    if (aaaserver == NULL)
+		return ERROR_RC;
+
+	data.send_pairs = send;
+	data.receive_pairs = NULL;
+    
+    if (add_nas_port != 0) {
+		/*
+		 * Fill in NAS-Port
+		 */
+		if (rc_avpair_add(rh, &(data.send_pairs), PW_NAS_PORT,
+		    &client_port, 0, 0) == NULL)
+			return ERROR_RC;
+	}
+    
+// -----------------------------------------------------------------------------    
+//
+#if 1    
+
+	skip_count = 0;
+	result = ERROR_RC;
+	for (i=0; (i < aaaserver->max) && (result != OK_RC) && (result != REJECT_RC)
+	    ; i++, now = rc_getctime())
+	{
+		if (aaaserver->deadtime_ends[i] != -1 &&
+		    aaaserver->deadtime_ends[i] > start_time) {
+			skip_count++;
+			continue;
+		}
+		if (data.receive_pairs != NULL) {
+			rc_avpair_free(data.receive_pairs);
+			data.receive_pairs = NULL;
+		}
+		rc_buildreq(rh, &data, request_type, aaaserver->name[i],
+		    aaaserver->port[i], aaaserver->secret[i], timeout, retries);
+
+		if (request_type == PW_ACCOUNTING_REQUEST) {
+			dtime = now - start_time;
+			rc_avpair_assign(adt_vp, &dtime, 0);
+		}
+
+		//result = rc_send_server (rh, &data, msg, type);
+		if (result == TIMEOUT_RC && radius_deadtime > 0)
+			aaaserver->deadtime_ends[i] = start_time + (double)radius_deadtime;
+	}
+	if (result == OK_RC || result == REJECT_RC || skip_count == 0)
+		goto exit;
+
+	result = ERROR_RC;
+	for (i=0; (i < aaaserver->max) && (result != OK_RC) && (result != REJECT_RC)
+	    ; i++)
+	{
+		if (aaaserver->deadtime_ends[i] == -1 ||
+		    aaaserver->deadtime_ends[i] <= start_time) {
+			continue;
+		}
+		if (data.receive_pairs != NULL) {
+			rc_avpair_free(data.receive_pairs);
+			data.receive_pairs = NULL;
+		}
+		rc_buildreq(rh, &data, request_type, aaaserver->name[i],
+		    aaaserver->port[i], aaaserver->secret[i], timeout, retries);
+
+		if (request_type == PW_ACCOUNTING_REQUEST) {
+			dtime = rc_getctime() - start_time;
+			rc_avpair_assign(adt_vp, &dtime, 0);
+		}
+
+		result = rc_send_server (rh, &data, msg, type);
+		if (result != TIMEOUT_RC)
+			aaaserver->deadtime_ends[i] = -1;
+	}
+
+exit:
+	if (request_type != PW_ACCOUNTING_REQUEST) {
+		*received = data.receive_pairs;
+	} else {
+		rc_avpair_free(data.receive_pairs);
+	}
+#endif
+	return result;
+  
+
+#if 0  
+	SEND_DATA   data;
+	VALUE_PAIR	*adt_vp = NULL;
+	int		    result;
+	int		    i, skip_count;
+	SERVER		*aaaserver;
+	int		    timeout = rc_conf_int(rh, "radius_timeout");
+	int		    retries = rc_conf_int(rh, "radius_retries");
+	int		    radius_deadtime = rc_conf_int(rh, "radius_deadtime");
+	double		start_time = 0;
+	double		now = 0;
+	time_t		dtime;
+	unsigned	type;
+
+	if (request_type != PW_ACCOUNTING_REQUEST) {
+		aaaserver = rc_conf_srv(rh, "authserver");
+		type = AUTH;
+	} else {
+		aaaserver = rc_conf_srv(rh, "acctserver");
+		type = ACCT;
+	}
+	if (aaaserver == NULL)
+		return ERROR_RC;
+
+	data.send_pairs = send;
+	data.receive_pairs = NULL;
+
+	if (add_nas_port != 0) {
+		/*
+		 * Fill in NAS-Port
+		 */
+		if (rc_avpair_add(rh, &(data.send_pairs), PW_NAS_PORT,
+		    &client_port, 0, 0) == NULL)
+			return ERROR_RC;
+	}
+
+	if (request_type == PW_ACCOUNTING_REQUEST) {
+		/*
+		 * Fill in Acct-Delay-Time
+		 */
+		dtime = 0;
+		now = rc_getctime();
+		adt_vp = rc_avpair_get(data.send_pairs, PW_ACCT_DELAY_TIME, 0);
+		if (adt_vp == NULL) {
+			adt_vp = rc_avpair_add(rh, &(data.send_pairs),
+			    PW_ACCT_DELAY_TIME, &dtime, 0, 0);
+			if (adt_vp == NULL)
+				return ERROR_RC;
+			start_time = now;
+		} else {
+			start_time = now - adt_vp->lvalue;
+		}
+	}
+
+	skip_count = 0;
+	result = ERROR_RC;
+	for (i=0; (i < aaaserver->max) && (result != OK_RC) && (result != REJECT_RC)
+	    ; i++, now = rc_getctime())
+	{
+		if (aaaserver->deadtime_ends[i] != -1 &&
+		    aaaserver->deadtime_ends[i] > start_time) {
+			skip_count++;
+			continue;
+		}
+		if (data.receive_pairs != NULL) {
+			rc_avpair_free(data.receive_pairs);
+			data.receive_pairs = NULL;
+		}
+		rc_buildreq(rh, &data, request_type, aaaserver->name[i],
+		    aaaserver->port[i], aaaserver->secret[i], timeout, retries);
+
+		if (request_type == PW_ACCOUNTING_REQUEST) {
+			dtime = now - start_time;
+			rc_avpair_assign(adt_vp, &dtime, 0);
+		}
+
+		//result = rc_send_server (rh, &data, msg, type);
+		if (result == TIMEOUT_RC && radius_deadtime > 0)
+			aaaserver->deadtime_ends[i] = start_time + (double)radius_deadtime;
+	}
+	if (result == OK_RC || result == REJECT_RC || skip_count == 0)
+		goto exit;
+
+	result = ERROR_RC;
+	for (i=0; (i < aaaserver->max) && (result != OK_RC) && (result != REJECT_RC)
+	    ; i++)
+	{
+		if (aaaserver->deadtime_ends[i] == -1 ||
+		    aaaserver->deadtime_ends[i] <= start_time) {
+			continue;
+		}
+		if (data.receive_pairs != NULL) {
+			rc_avpair_free(data.receive_pairs);
+			data.receive_pairs = NULL;
+		}
+		rc_buildreq(rh, &data, request_type, aaaserver->name[i],
+		    aaaserver->port[i], aaaserver->secret[i], timeout, retries);
+
+		if (request_type == PW_ACCOUNTING_REQUEST) {
+			dtime = rc_getctime() - start_time;
+			rc_avpair_assign(adt_vp, &dtime, 0);
+		}
+
+		//result = rc_send_server (rh, &data, msg, type);
+		if (result != TIMEOUT_RC)
+			aaaserver->deadtime_ends[i] = -1;
+	}
+
+exit:
+	if (request_type != PW_ACCOUNTING_REQUEST) {
+		*received = data.receive_pairs;
+	} else {
+		rc_avpair_free(data.receive_pairs);
+	}
+
+	return result;
+#endif    
+}
+
+/** Builds an authentication request for port id client_port with the value_pairs send and submits it to a server
+ *
+ * @param rh a handle to parsed configuration.
+ * @param client_port the client port number to use (may be zero to use any available).
+ * @param send a #VALUE_PAIR array of values (e.g., %PW_USER_NAME).
+ * @param received an allocated array of received values.
+ * @param msg must be an array of %PW_MAX_MSG_SIZE or %NULL; will contain the concatenation of any
+ *	%PW_REPLY_MESSAGE received.
+ * @return received value_pairs in @received, messages from the server in msg (if non-NULL),
+ *	and %OK_RC (0) on success, negative on failure as return value.
+ */
+int rc_auth(rc_handle *rh, uint32_t client_port, VALUE_PAIR *send, VALUE_PAIR **received,
+    char *msg)
+{
+
+	//return rc_aaa(rh, client_port, send, received, msg, 1, PW_ACCESS_REQUEST);
+    return rc_aaa(rh, client_port, send, received, msg, 0, PW_ACCESS_REQUEST);
+}
+
+/** Builds an authentication request for proxying
+ *
+ * Builds an authentication request with the value_pairs send and submits it to a server.
+ * Works for a proxy; does not add IP address, and does does not rely on config file.
+ *
+ * @param rh a handle to parsed configuration.
+ * @param client_port the client port number to use (may be zero to use any available).
+ * @param send a #VALUE_PAIR array of values (e.g., %PW_USER_NAME).
+ * @param received an allocated array of received values.
+ * @param msg must be an array of %PW_MAX_MSG_SIZE or %NULL; will contain the concatenation of
+ *	any %PW_REPLY_MESSAGE received.
+ * @return received value_pairs in @received, messages from the server in msg (if non-NULL)
+ *	and %OK_RC (0) on success, negative on failure as return value.
+ */
+int rc_auth_proxy(rc_handle *rh, VALUE_PAIR *send, VALUE_PAIR **received, char *msg)
+{
+	return rc_aaa(rh, 0, send, received, msg, 0, PW_ACCESS_REQUEST);
+}
+
+/** Builds an accounting request for port id client_port with the value_pairs at send
+ *
+ * @note NAS-IP-Address, NAS-Port and Acct-Delay-Time get filled in by this function, the rest has to be supplied.
+ *
+ * @param rh a handle to parsed configuration.
+ * @param client_port the client port number to use (may be zero to use any available).
+ * @param send a #VALUE_PAIR array of values (e.g., %PW_USER_NAME).
+ * @return received value_pairs in @received, and %OK_RC (0) on success, negative on failure as return value.
+ */
+int rc_acct(rc_handle *rh, uint32_t client_port, VALUE_PAIR *send)
+{
+	return rc_aaa(rh, client_port, send, NULL, NULL, 1, PW_ACCOUNTING_REQUEST);
+}
+
+/** Builds an accounting request with the value_pairs at send
+ *
+ * @param rh a handle to parsed configuration.
+ * @param send a #VALUE_PAIR array of values (e.g., %PW_USER_NAME).
+ * @return %OK_RC (0) on success, negative on failure as return value.
+ */
+int rc_acct_proxy(rc_handle *rh, VALUE_PAIR *send)
+{
+
+	return rc_aaa(rh, 0, send, NULL, NULL, 0, PW_ACCOUNTING_REQUEST);
+}
+
+/** Asks the server hostname on the specified port for a status message
+ *
+ * @param rh a handle to parsed configuration.
+ * @param host the name of the server.
+ * @param secret the secret used by the server.
+ * @param port the server's port number.
+ * @param msg must be an array of %PW_MAX_MSG_SIZE or %NULL; will contain the concatenation of any
+ *	%PW_REPLY_MESSAGE received.
+ * @return %OK_RC (0) on success, negative on failure as return value.
+ */
+int rc_check(rc_handle *rh, char *host, char *secret, unsigned short port, char *msg)
+{
+	SEND_DATA       data;
+	int		result;
+	uint32_t		service_type;
+	int		timeout = rc_conf_int(rh, "radius_timeout");
+	int		retries = rc_conf_int(rh, "radius_retries");
+
+	data.send_pairs = data.receive_pairs = NULL;
+
+	/*
+	 * Fill in Service-Type
+	 */
+
+	service_type = PW_ADMINISTRATIVE;
+	rc_avpair_add(rh, &(data.send_pairs), PW_SERVICE_TYPE, &service_type, 0, 0);
+
+	rc_buildreq(rh, &data, PW_STATUS_SERVER, host, port, secret, timeout, retries);
+	//result = rc_send_server (rh, &data, msg, ACCT);
+
+	rc_avpair_free(data.receive_pairs);
+
+	return result;
+}

+ 137 - 0
thirdparty/FreeRadius/lib/clientid.c

@@ -0,0 +1,137 @@
+/*
+ * $Id: clientid.c,v 1.7 2007/07/11 17:29:29 cparker Exp $
+ *
+ * Copyright (C) 1995,1996,1997 Lars Fenneberg
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+#include <config.h>
+#include <includes.h>
+#include <freeradius-client.h>
+#include "util.h"
+
+struct map2id_s {
+	char *name;
+	uint32_t id;
+
+	struct map2id_s *next;
+};
+
+/** Read in the ttyname to port id map file
+ *
+ * @param rh a handle to parsed configuration.
+ * @param filename the file name of the map file.
+ * @return zero on success, negative integer on failure.
+ */
+int rc_read_mapfile(rc_handle *rh, char const *filename)
+{
+	char buffer[1024];
+	FILE *mapfd;
+	char *c, *name, *id, *q;
+	struct map2id_s *p;
+	int lnr = 0;
+
+        if ((mapfd = fopen(filename,"r")) == NULL)
+        {
+		rc_log(LOG_ERR,"rc_read_mapfile: can't read %s: %s", filename, strerror(errno));
+		return -1;
+	}
+
+#define SKIP(p) while(*p && isspace(*p)) p++;
+
+        while (fgets(buffer, sizeof(buffer), mapfd) != NULL)
+        {
+        	lnr++;
+
+		q = buffer;
+
+                SKIP(q);
+
+                if ((*q == '\n') || (*q == '#') || (*q == '\0'))
+			continue;
+
+		if (( c = strchr(q, ' ')) || (c = strchr(q,'\t'))) {
+
+			*c = '\0'; c++;
+			SKIP(c);
+
+			name = q;
+			id = c;
+
+			if ((p = (struct map2id_s *)malloc(sizeof(*p))) == NULL) {
+				rc_log(LOG_CRIT,"rc_read_mapfile: out of memory");
+				fclose(mapfd);
+				return -1;
+			}
+
+			p->name = strdup(name);
+			p->id = atoi(id);
+			p->next = rh->map2id_list;
+			rh->map2id_list = p;
+
+		} else {
+
+			rc_log(LOG_ERR, "rc_read_mapfile: malformed line in %s, line %d", filename, lnr);
+			fclose(mapfd);
+			return -1;
+
+		}
+	}
+
+#undef SKIP
+
+	fclose(mapfd);
+
+	return 0;
+}
+
+/** Maps ttyname to port id
+ *
+ * @param rh a handle to parsed configuration.
+ * @param name full pathname of the tty.
+ * @return port id, or zero if no entry found.
+ */
+uint32_t rc_map2id(rc_handle const *rh, char const *name)
+{
+	struct map2id_s *p;
+	char ttyname[PATH_MAX];
+	unsigned pos = 0;
+
+	*ttyname = '\0';
+	if (*name != '/') {
+		strcpy(ttyname, "/dev/");
+		pos = 5;
+	}
+
+	strlcpy(&ttyname[pos], name, sizeof(ttyname)-pos);
+
+	for(p = rh->map2id_list; p; p = p->next)
+		if (!strcmp(ttyname, p->name)) return p->id;
+
+	rc_log(LOG_WARNING,"rc_map2id: can't find tty %s in map database", ttyname);
+
+	return 0;
+}
+
+/** Free allocated map2id list
+ *
+ * @param rh a handle to parsed configuration.
+ */
+void rc_map2id_free(rc_handle *rh)
+{
+	struct map2id_s *p, *np;
+
+	if (rh->map2id_list == NULL)
+		return;
+
+	for(p = rh->map2id_list; p != NULL; p = np) {
+		np = p->next;
+		free(p->name);
+		free(p);
+	}
+	rh->map2id_list = NULL;
+}

+ 939 - 0
thirdparty/FreeRadius/lib/config.c

@@ -0,0 +1,939 @@
+/*
+ * $Id: config.c,v 1.23 2010/04/28 14:26:15 aland Exp $
+ *
+ * Copyright (C) 1995,1996,1997 Lars Fenneberg
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ *
+ * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
+ * and Merit Network, Inc. All Rights Reserved
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+#include <radius_config.h>
+#include <includes.h>
+#include <freeradius-client.h>
+#include <fr_options.h>
+#include "util.h"
+
+extern OPTION      rcOptions;
+
+/** Find an option in the option list
+ *
+ * @param rh a handle to parsed configuration.
+ * @param optname the name of the option.
+ * @param type the option type.
+ * @return pointer to option on success, NULL otherwise.
+ */
+static OPTION *find_option(rc_handle const *rh, char const *optname, unsigned int type)
+{
+	int 	i;
+
+	/* there're so few options that a binary search seems not necessary */
+	for (i = 0; i < NUM_OPTIONS; i++) {
+		if (!strcmp(rh->config_options[i].name, optname) &&
+		    (rh->config_options[i].type & type))
+		{
+		    	return &rh->config_options[i];
+		}
+	}
+
+	return NULL;
+}
+
+/** Set a specific option doing type conversions
+ *
+ * @param filename the name of the config file (for logging purposes).
+ * @param line the line number in the file.
+ * @param p Value.
+ * @return 0 on success, -1 on failure.
+ */
+static int set_option_str(char const *filename, int line, OPTION *option, char const *p)
+{
+	if (p) {
+		option->val = (void *) strdup(p);
+		if (option->val == NULL) {
+			rc_log(LOG_CRIT, "read_config: out of memory");
+			return -1;
+		}
+	} else {
+		option->val = NULL;
+	}
+
+	return 0;
+}
+
+static int set_option_int(char const *filename, int line, OPTION *option, char const *p)
+{
+	int *iptr;
+
+	if (p == NULL) {
+		rc_log(LOG_ERR, "%s: line %d: bogus option value", filename, line);
+		return -1;
+	}
+
+	if ((iptr = malloc(sizeof(*iptr))) == NULL) {
+		rc_log(LOG_CRIT, "read_config: out of memory");
+		return -1;
+	}
+
+	*iptr = atoi(p);
+	option->val = (void *) iptr;
+
+	return 0;
+}
+
+static int set_option_srv(char const *filename, int line, OPTION *option, char const *p)
+{
+#if 0  
+	SERVER *serv;
+	char *p_pointer;
+	char *p_dupe;
+	char *p_save;
+	char *q;
+	char *s;
+	struct servent *svp;
+
+	p_dupe = strdup(p);
+
+	if (p_dupe == NULL) {
+		rc_log(LOG_ERR, "%s: line %d: Invalid option or memory failure", filename, line);
+		return -1;
+	}
+
+	serv = (SERVER *) option->val;
+	if (serv == NULL) {
+		DEBUG(LOG_ERR, "option->val / server is NULL, allocating memory");
+		serv = malloc(sizeof(*serv));
+		if (serv == NULL) {
+			rc_log(LOG_CRIT, "read_config: out of memory");
+			free(p_dupe);
+			return -1;
+		}
+		memset(serv, 0, sizeof(*serv));
+		serv->max = 0;
+	}
+
+	p_pointer = strtok_r(p_dupe, ", \t", &p_save);
+
+	/* check to see for '[IPv6]:port' syntax */
+	if ((q = strchr(p_pointer,'[')) != NULL) {
+		*q = '\0';
+		q++;
+		p_pointer = q;
+
+		q = strchr(p_pointer, ']');
+		if (q == NULL) {
+			free(p_dupe);
+			rc_log(LOG_CRIT, "read_config: IPv6 parse error");
+			return -1;
+		}
+		*q = '\0';
+		q++;
+
+		if (q[0] == ':') {
+			q++;
+		}
+
+		/* Check to see if we have '[IPv6]:port:secret' syntax */
+		if((s=strchr(q, ':')) != NULL) {
+			*s = '\0';
+			s++;
+			serv->secret[serv->max] = strdup(s);
+			if (serv->secret[serv->max] == NULL) {
+				rc_log(LOG_CRIT, "read_config: out of memory");
+				if (option->val == NULL) {
+					free(p_dupe);
+					free(serv);
+				}
+				return -1;
+			}
+		}
+
+	} else /* Check to see if we have 'servername:port' syntax */
+	if ((q = strchr(p_pointer,':')) != NULL) {
+		*q = '\0';
+		q++;
+
+		/* Check to see if we have 'servername:port:secret' syntax */
+		if((s = strchr(q,':')) != NULL) {
+			*s = '\0';
+			s++;
+			serv->secret[serv->max] = strdup(s);
+			if (serv->secret[serv->max] == NULL) {
+				rc_log(LOG_CRIT, "read_config: out of memory");
+				if (option->val == NULL) {
+					free(p_dupe);
+					free(serv);
+				}
+				return -1;
+			}
+		}
+	}
+
+	if(q && strlen(q) > 0) {
+		serv->port[serv->max] = atoi(q);
+	} else {
+		if (!strcmp(option->name,"authserver"))
+			if ((svp = getservbyname ("radius", "udp")) == NULL)
+				serv->port[serv->max] = PW_AUTH_UDP_PORT;
+			else
+				serv->port[serv->max] = ntohs ((unsigned int) svp->s_port);
+		else if (!strcmp(option->name, "acctserver"))
+			if ((svp = getservbyname ("radacct", "udp")) == NULL)
+				serv->port[serv->max] = PW_ACCT_UDP_PORT;
+			else
+				serv->port[serv->max] = ntohs ((unsigned int) svp->s_port);
+		else {
+			rc_log(LOG_ERR, "%s: line %d: no default port for %s", filename, line, option->name);
+			if (option->val == NULL) {
+				free(p_dupe);
+				free(serv);
+			}
+			return -1;
+		}
+	}
+
+	serv->name[serv->max] = strdup(p_pointer);
+	if (serv->name[serv->max] == NULL) {
+		rc_log(LOG_CRIT, "read_config: out of memory");
+		if (option->val == NULL) {
+			free(p_dupe);
+			free(serv);
+		}
+		return -1;
+	}
+	free(p_dupe);
+
+	serv->deadtime_ends[serv->max] = -1;
+	serv->max++;
+
+	if (option->val == NULL)
+		option->val = (void *)serv;
+#endif
+	return 0;
+
+}
+
+static int set_option_auo(char const *filename, int line, OPTION *option, char const *p)
+{
+	int *iptr;
+	char *p_dupe = NULL;
+	char *p_pointer = NULL;
+	char *p_save = NULL;
+
+	p_dupe = strdup(p);
+
+	if (p_dupe == NULL) {
+		rc_log(LOG_WARNING, "%s: line %d: bogus option value", filename, line);
+		return -1;
+	}
+
+	if ((iptr = malloc(sizeof(iptr))) == NULL) {
+			rc_log(LOG_CRIT, "read_config: out of memory");
+			free(p_dupe);
+			return -1;
+	}
+
+	*iptr = 0;
+	p_pointer = strtok_r(p_dupe, ", \t", &p_save);
+
+	if (!strncmp(p_pointer, "local", 5))
+			*iptr = AUTH_LOCAL_FST;
+	else if (!strncmp(p_pointer, "radius", 6))
+			*iptr = AUTH_RADIUS_FST;
+	else {
+		rc_log(LOG_ERR,"%s: auth_order: unknown keyword: %s", filename, p);
+		free(iptr);
+		free(p_dupe);
+		return -1;
+	}
+
+	p_pointer = strtok_r(NULL, ", \t", &p_save);
+
+	if (p_pointer && (*p_pointer != '\0')) {
+		if ((*iptr & AUTH_RADIUS_FST) && !strcmp(p_pointer, "local"))
+			*iptr = (*iptr) | AUTH_LOCAL_SND;
+		else if ((*iptr & AUTH_LOCAL_FST) && !strcmp(p_pointer, "radius"))
+			*iptr = (*iptr) | AUTH_RADIUS_SND;
+		else {
+			rc_log(LOG_ERR,"%s: auth_order: unknown or unexpected keyword: %s", filename, p);
+			free(iptr);
+			free(p_dupe);
+			return -1;
+		}
+	}
+
+	option->val = (void *) iptr;
+
+	free(p_dupe);
+	return 0;
+}
+
+/** Allow a config option to be added to rc_handle from inside a program
+ *
+ * @param rh a handle to parsed configuration.
+ * @param option_name the name of the option.
+ * @param option_val the value to be added.
+ * @param source typically should be %__FILE__ or %__func__ for logging purposes.
+ * @param line %__LINE__ for logging purposes.
+ * @return 0 on success, -1 on failure.
+ */
+int rc_add_config(rc_handle *rh, char const *option_name, char const *option_val, char const *source, int line)
+{
+	OPTION *option;
+
+	if ((option = find_option(rh, option_name, OT_ANY)) == NULL)
+	{
+		rc_log(LOG_ERR, "ERROR: unrecognized option: %s", option_name);
+		return -1;
+	}
+
+	if (option->status != ST_UNDEF)
+	{
+		rc_log(LOG_ERR, "ERROR: duplicate option: %s", option_name);
+		return -1;
+	}
+
+	switch (option->type) {
+		case OT_STR:
+			if (set_option_str(source, line, option, option_val) < 0) {
+				return -1;
+			}
+			break;
+		case OT_INT:
+			if (set_option_int(source, line, option, option_val) < 0) {
+				return -1;
+			}
+			break;
+		case OT_SRV:
+			if (set_option_srv(source, line, option, option_val) < 0) {
+				return -1;
+			}
+			break;
+		case OT_AUO:
+			if (set_option_auo(source, line, option, option_val) < 0) {
+				return -1;
+			}
+			break;
+		default:
+			rc_log(LOG_CRIT, "rc_add_config: impossible case branch!");
+			abort();
+	}
+
+	if (strcmp(option->name, "bindaddr") == 0) {
+		memset(&rh->own_bind_addr, 0, sizeof(rh->own_bind_addr));
+		rh->own_bind_addr_set = 0;
+		rc_own_bind_addr(rh, &rh->own_bind_addr);
+		rh->own_bind_addr_set = 1;
+	}
+
+	return 0;
+}
+
+/** Initialise a configuration structure
+ *
+ * Initialize the configuration structure from an external program.  For use when not
+ * running a standalone client that reads from a config file.
+ *
+ * @param rh a handle to parsed configuration.
+ * @return rc_handle on success, NULL on failure.
+ */
+rc_handle *rc_config_init(rc_handle *rh)
+{
+	int i;
+	SERVER *authservers;
+	SERVER *acctservers;
+	OPTION *acct;
+	OPTION *auth;
+
+        rh->config_options = malloc(sizeof(config_options_default));
+        if (rh->config_options == NULL)
+	{
+                rc_log(LOG_CRIT, "rc_config_init: out of memory");
+		rc_destroy(rh);
+                return NULL;
+        }
+        memcpy(rh->config_options, &config_options_default, sizeof(config_options_default));
+
+	acct = find_option(rh, "acctserver", OT_ANY);
+	auth = find_option(rh, "authserver", OT_ANY);
+	authservers = malloc(sizeof(SERVER));
+	acctservers = malloc(sizeof(SERVER));
+
+	if(authservers == NULL || acctservers == NULL)
+	{
+                rc_log(LOG_CRIT, "rc_config_init: error initializing server structs");
+		rc_destroy(rh);
+		if(authservers) free(authservers);
+		if(acctservers) free(acctservers);
+                return NULL;
+	}
+
+
+	authservers->max = 0;
+	acctservers->max = 0;
+
+	for(i=0; i < SERVER_MAX; i++)
+	{
+		authservers->name[i] = NULL;
+		authservers->secret[i] = NULL;
+		acctservers->name[i] = NULL;
+		acctservers->secret[i] = NULL;
+	}
+	acct->val = acctservers;
+	auth->val = authservers;
+	return rh;
+}
+
+/** Read the global config file
+ *
+ * @param filename a name of a file.
+ * @return new rc_handle on success, NULL when failure.
+ */
+void rc_read_config(rc_handle* rh)
+{
+    // TODO запускаем random generator
+        
+    rh->config_options = &rcOptions;
+    
+    //memcpy(rh->config_options, &config_options_default, sizeof(config_options_default));
+}
+
+#if 0
+rc_handle *rc_read_config(char const *filename)
+{
+	FILE *configfd;
+	char buffer[512], *p;
+	OPTION *option;
+	int line;
+	size_t pos;
+	rc_handle *rh;
+
+	srandom((unsigned int)(time(NULL)+getpid()));
+
+	rh = rc_new();
+	if (rh == NULL)
+		return NULL;
+
+        rh->config_options = malloc(sizeof(config_options_default));
+        if (rh->config_options == NULL) {
+            rc_log(LOG_CRIT, "rc_read_config: out of memory");
+            rc_destroy(rh);
+            return NULL;
+        }
+        memcpy(rh->config_options, &config_options_default, sizeof(config_options_default));
+
+	if ((configfd = fopen(filename,"r")) == NULL)
+	{
+		rc_log(LOG_ERR,"rc_read_config: can't open %s: %s", filename, strerror(errno));
+		rc_destroy(rh);
+		return NULL;
+	}
+
+	line = 0;
+	while ((fgets(buffer, sizeof(buffer), configfd) != NULL))
+	{
+		line++;
+		p = buffer;
+
+		if ((*p == '\n') || (*p == '#') || (*p == '\0'))
+			continue;
+
+		p[strlen(p)-1] = '\0';
+
+
+		if ((pos = strcspn(p, "\t ")) == 0) {
+			rc_log(LOG_ERR, "%s: line %d: bogus format: %s", filename, line, p);
+			fclose(configfd);
+			rc_destroy(rh);
+			return NULL;
+		}
+
+		p[pos] = '\0';
+
+		if ((option = find_option(rh, p, OT_ANY)) == NULL) {
+			rc_log(LOG_ERR, "%s: line %d: unrecognized keyword: %s", filename, line, p);
+			fclose(configfd);
+			rc_destroy(rh);
+			return NULL;
+		}
+
+		if (option->status != ST_UNDEF) {
+			rc_log(LOG_ERR, "%s: line %d: duplicate option line: %s", filename, line, p);
+			fclose(configfd);
+			rc_destroy(rh);
+			return NULL;
+		}
+
+		p += pos+1;
+		while (isspace(*p))
+			p++;
+		pos = strlen(p) - 1;
+		while(pos != 0 && isspace(p[pos]))
+			pos--;
+		p[pos + 1] = '\0';
+
+		switch (option->type) {
+			case OT_STR:
+				if (set_option_str(filename, line, option, p) < 0) {
+					fclose(configfd);
+					rc_destroy(rh);
+				 	return NULL;
+				}
+				break;
+			case OT_INT:
+				if (set_option_int(filename, line, option, p) < 0) {
+					fclose(configfd);
+					rc_destroy(rh);
+				 	return NULL;
+				}
+				break;
+			case OT_SRV:
+				if (set_option_srv(filename, line, option, p) < 0) {
+					fclose(configfd);
+					rc_destroy(rh);
+				 	return NULL;
+				}
+				break;
+			case OT_AUO:
+				if (set_option_auo(filename, line, option, p) < 0) {
+					fclose(configfd);
+					rc_destroy(rh);
+				 	return NULL;
+				}
+				break;
+			default:
+				rc_log(LOG_CRIT, "rc_read_config: impossible case branch!");
+				abort();
+		}
+	}
+	fclose(configfd);
+
+	if (test_config(rh, filename) == -1) {
+		rc_destroy(rh);
+		return NULL;
+	}
+	return rh;
+}
+#endif
+
+/** Get the value of a config option
+ *
+ * @param rh a handle to parsed configuration.
+ * @param optname the name of an option.
+ * @return config option value.
+ */
+char *rc_conf_str(rc_handle const *rh, char const *optname)
+{
+	OPTION *option;
+
+	option = find_option(rh, optname, OT_STR);
+
+	if (option != NULL) {
+		return (char *)option->val;
+	} else {
+		rc_log(LOG_CRIT, "rc_conf_str: unkown config option requested: %s", optname);
+		return NULL;
+	}
+}
+
+/** Get the value of a config option
+ *
+ * @param rh a handle to parsed configuration.
+ * @param optname the name of an option.
+ * @return config option value.
+ */
+int rc_conf_int(rc_handle const *rh, char const *optname)
+{
+	OPTION *option;
+
+	option = find_option(rh, optname, OT_INT|OT_AUO);
+
+	if (option != NULL) {
+		if (option->val) {
+			return *((int *)option->val);
+		} else {
+			rc_log(LOG_ERR, "rc_conf_int: config option %s was not set", optname);
+			return 0;
+		}
+	} else {
+		rc_log(LOG_CRIT, "rc_conf_int: unkown config option requested: %s", optname);
+		return 0;
+	}
+}
+
+/** Get the value of a config option
+ *
+ * @param rh a handle to parsed configuration.
+ * @param optname the name of an option.
+ * @return config option value.
+ */
+SERVER *rc_conf_srv(rc_handle const *rh, char const *optname)
+{
+	OPTION *option;
+
+	option = find_option(rh, optname, OT_SRV);
+
+	if (option != NULL) {
+		return (SERVER *)option->val;
+	} else {
+		rc_log(LOG_CRIT, "rc_conf_srv: unkown config option requested: %s", optname);
+		return NULL;
+	}
+}
+
+/** Tests the configuration the user supplied
+ *
+ * @param rh a handle to parsed configuration.
+ * @param filename a name of a configuration file.
+ * @return 0 on success, -1 when failure.
+ */
+int test_config(rc_handle const *rh, char const *filename)
+{
+	SERVER *srv;
+
+	srv = rc_conf_srv(rh, "authserver");
+	if (!srv || !srv->max)
+	{
+		rc_log(LOG_ERR,"%s: no authserver specified", filename);
+		return -1;
+	}
+
+	srv = rc_conf_srv(rh, "acctserver");
+	if (!srv || !srv->max)
+	{
+		rc_log(LOG_ERR,"%s: no acctserver specified", filename);
+		return -1;
+	}
+	if (!rc_conf_str(rh, "servers"))
+	{
+		rc_log(LOG_ERR,"%s: no servers file specified", filename);
+		return -1;
+	}
+	if (!rc_conf_str(rh, "dictionary"))
+	{
+		rc_log(LOG_ERR,"%s: no dictionary specified", filename);
+		return -1;
+	}
+
+	if (rc_conf_int(rh, "radius_timeout") <= 0)
+	{
+		rc_log(LOG_ERR,"%s: radius_timeout <= 0 is illegal", filename);
+		return -1;
+	}
+	if (rc_conf_int(rh, "radius_retries") <= 0)
+	{
+		rc_log(LOG_ERR,"%s: radius_retries <= 0 is illegal", filename);
+		return -1;
+	}
+	if (rc_conf_int(rh, "radius_deadtime") < 0)
+	{
+		rc_log(LOG_ERR,"%s: radius_deadtime is illegal", filename);
+		return -1;
+	}
+	if (rc_conf_int(rh, "login_tries") <= 0)
+	{
+		rc_log(LOG_ERR,"%s: login_tries <= 0 is illegal", filename);
+		return -1;
+	}
+	if (rc_conf_int(rh, "login_timeout") <= 0)
+	{
+		rc_log(LOG_ERR,"%s: login_timeout <= 0 is illegal", filename);
+		return -1;
+	}
+	if (rc_conf_str(rh, "mapfile") == NULL)
+	{
+		rc_log(LOG_ERR,"%s: mapfile not specified", filename);
+		return -1;
+	}
+	if (rc_conf_str(rh, "nologin") == NULL)
+	{
+		rc_log(LOG_ERR,"%s: nologin not specified", filename);
+		return -1;
+	}
+
+	return 0;
+}
+
+/** See if info matches hostname
+ *
+ * @param info a struct addrinfo
+ * @param hostname the name of the host.
+ * @return 0 on success, -1 when failure.
+ */
+static int find_match (const struct addrinfo* addr, const struct addrinfo *hostname)
+{
+#if 0  
+	const struct addrinfo *ptr, *ptr2;
+	unsigned len1, len2;
+
+	ptr = addr;
+	while(ptr) {
+		ptr2 = hostname;
+		while(ptr2) {
+			len1 = SA_GET_INLEN(ptr->ai_addr);
+			len2 = SA_GET_INLEN(ptr2->ai_addr);
+
+			if (len1 > 0 && 
+			    len1 == len2 && 
+			    memcmp(SA_GET_INADDR(ptr->ai_addr), SA_GET_INADDR(ptr2->ai_addr), len1) == 0) {
+				return 0;
+			}
+			ptr2 = ptr2->ai_next;
+ 		}
+		ptr = ptr->ai_next;
+ 	}
+#endif    
+ 	return -1;
+}
+
+/** Checks if provided address is local address
+ *
+ * @param addr an %AF_INET or %AF_INET6 address
+ * @return 0 if local, 1 if not local, -1 on failure.
+ */
+static int rc_ipaddr_local(const struct sockaddr *addr)
+{
+#if 0  
+	int temp_sock, res, serrno;
+	struct sockaddr tmpaddr;
+
+	memcpy(&tmpaddr, addr, SA_LEN(addr));
+
+	temp_sock = socket(addr->sa_family, SOCK_DGRAM, 0);
+	if (temp_sock == -1)
+		return -1;
+
+	if (addr->sa_family == AF_INET) {
+		((struct sockaddr_in*)&tmpaddr)->sin_port = 0;
+	} else {
+		((struct sockaddr_in6*)&tmpaddr)->sin6_port = 0;
+	}
+	res = bind(temp_sock, &tmpaddr, SA_LEN(&tmpaddr));
+	serrno = errno;
+	close(temp_sock);
+	if (res == 0)
+		return 0;
+	if (serrno == EADDRNOTAVAIL)
+		return 1;
+#endif    
+	return -1;
+}
+
+/** Checks if provided name refers to ourselves
+ *
+ * @param info an addrinfo of the host to check
+ * @return 0 if yes, 1 if no and -1 on failure.
+ */
+static int rc_is_myname(const struct addrinfo *info)
+{
+#if 0  
+	const struct addrinfo *p;
+	int	res;
+
+	p = info;
+	while(p != NULL) {
+		res = rc_ipaddr_local(p->ai_addr);
+		if (res == 0 || res == -1) {
+ 			return res;
+		}
+		p = p->ai_next;
+ 	}
+#endif    
+ 	return 1;
+}
+
+/** Locate a server in the rh config or if not found, check for a servers file
+ *
+ * @param rh a handle to parsed configuration.
+ * @param server_name the name of the server.
+ * @param info: will hold a pointer to addrinfo
+ * @param secret will hold the server's secret (of %MAX_SECRET_LENGTH).
+ * @param flags %AUTH or %ACCT
+ 
+ * @return 0 on success, -1 on failure.
+ */
+//int rc_find_server_addr(rc_handle const *, char const *, struct addrinfo **, char *, unsigned flags);
+
+int rc_find_server_addr(rc_handle const *rh, char const *server_name,
+                        struct addrinfo** info, char *secret, unsigned flags)
+{
+	int		i;
+	int             result = 0;
+	FILE           *clientfd;
+	char           *h;
+	char           *s;
+	char            buffer[128];
+	char            hostnm[AUTH_ID_LEN + 1];
+	char	       *buffer_save;
+	char	       *hostnm_save;
+	SERVER	       *authservers;
+	SERVER	       *acctservers;
+	struct addrinfo *tmpinfo = NULL;
+
+	/* Lookup the IP address of the radius server */
+	if ((*info = rc_getaddrinfo (server_name, flags==AUTH?PW_AI_AUTH:PW_AI_ACCT)) == NULL)
+		return -1;
+
+	if (flags == AUTH) {
+		/* Check to see if the server secret is defined in the rh config */
+		if( (authservers = rc_conf_srv(rh, "authserver")) != NULL )
+		{
+			for( i = 0; i < authservers->max; i++ )
+			{
+				if( (strncmp(server_name, authservers->name[i], strlen(server_name)) == 0) &&
+				    (authservers->secret[i] != NULL) )
+				{
+					memset (secret, '\0', MAX_SECRET_LENGTH);
+					strlcpy (secret, authservers->secret[i], MAX_SECRET_LENGTH);
+					return 0;
+				}
+			}
+		}
+	} else if (flags == ACCT) {
+		if( (acctservers = rc_conf_srv(rh, "acctserver")) != NULL )
+		{
+			for( i = 0; i < acctservers->max; i++ )
+			{
+				if( (strncmp(server_name, acctservers->name[i], strlen(server_name)) == 0) &&
+				    (acctservers->secret[i] != NULL) )
+				{
+					memset (secret, '\0', MAX_SECRET_LENGTH);
+					strlcpy (secret, acctservers->secret[i], MAX_SECRET_LENGTH);
+					return 0;
+				}
+			}
+		}
+	}
+
+	/* We didn't find it in the rh_config or the servername is too long so look for a
+	 * servers file to define the secret(s)
+	 */
+
+	if ((clientfd = fopen (rc_conf_str(rh, "servers"), "r")) == NULL)
+	{
+		rc_log(LOG_ERR, "rc_find_server: couldn't open file: %s: %s", strerror(errno), rc_conf_str(rh, "servers"));
+		goto fail;
+	}
+
+	while (fgets (buffer, sizeof (buffer), clientfd) != NULL)
+	{
+		if (*buffer == '#')
+			continue;
+
+		if ((h = strtok_r(buffer, " \t\n", &buffer_save)) == NULL) /* first hostname */
+			continue;
+
+		strlcpy (hostnm, h, AUTH_ID_LEN);
+
+		if ((s = strtok_r (NULL, " \t\n", &buffer_save)) == NULL) /* and secret field */
+			continue;
+
+		strlcpy (secret, s, MAX_SECRET_LENGTH);
+
+		if (!strchr (hostnm, '/')) /* If single name form */
+		{
+			tmpinfo = rc_getaddrinfo(hostnm, 0);
+			if (tmpinfo)
+			{
+				result = find_match (*info, tmpinfo);
+				if (result == 0)
+				{
+					result++;
+					break;
+				}
+
+				//freeaddrinfo(tmpinfo);
+				tmpinfo = NULL;
+			}
+		}
+		else /* <name1>/<name2> "paired" form */
+		{
+			strtok_r(hostnm, "/", &hostnm_save);
+			tmpinfo = rc_getaddrinfo(hostnm, 0);
+			if (tmpinfo)
+			{
+				if (rc_is_myname(tmpinfo) == 0)
+				{	     /* If we're the 1st name, target is 2nd */
+					if (find_match (*info, tmpinfo) == 0)
+					{
+						result++;
+						break;
+					}
+				}
+				else	/* If we were 2nd name, target is 1st name */
+				{
+					if (find_match (*info, tmpinfo) == 0)
+					{
+						result++;
+						break;
+					}
+				}
+				//freeaddrinfo(tmpinfo);
+				tmpinfo = NULL;
+			}
+		}
+	}
+	fclose (clientfd);
+	if (result == 0)
+	{
+		memset (buffer, '\0', sizeof (buffer));
+		memset (secret, '\0', MAX_SECRET_LENGTH);
+		rc_log(LOG_ERR, "rc_find_server: couldn't find RADIUS server %s in %s",
+			 server_name, rc_conf_str(rh, "servers"));
+		goto fail;
+	}
+	
+	result = 0;
+	goto cleanup;
+
+ fail:
+ 	//freeaddrinfo(*info);
+ 	result = -1;
+
+ cleanup:
+ 	//if (tmpinfo)
+ 		//freeaddrinfo(tmpinfo);
+
+	return result;
+}
+
+/**
+ * rc_config_free:
+ * @param rh a handle to parsed configuration
+ *
+ * Free allocated config values
+ *
+ */
+
+void
+rc_config_free(rc_handle *rh)
+{
+	int i, j;
+	SERVER *serv;
+
+	if (rh->config_options == NULL)
+		return;
+
+	for (i = 0; i < NUM_OPTIONS; i++) {
+		if (rh->config_options[i].val == NULL)
+			continue;
+		if (rh->config_options[i].type == OT_SRV) {
+		        serv = (SERVER *)rh->config_options[i].val;
+			for (j = 0; j < serv->max; j++){
+				free(serv->name[j]);
+				if(serv->secret[j]) free(serv->secret[j]);
+			}
+			free(serv);
+		} else {
+			free(rh->config_options[i].val);
+		}
+	}
+	free(rh->config_options);
+	rh->config_options = NULL;
+}

+ 501 - 0
thirdparty/FreeRadius/lib/dict.c

@@ -0,0 +1,501 @@
+/*
+ * $Id: dict.c,v 1.10 2007/07/11 17:29:29 cparker Exp $
+ *
+ * Copyright (C) 1995,1996,1997 Lars Fenneberg
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ *
+ * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
+ * and Merit Network, Inc. All Rights Reserved
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+#include <radius_config.h>
+#include <includes.h>
+#include <freeradius-client.h>
+
+/** Initialize the dictionary
+ *
+ * Read all ATTRIBUTES into the dictionary_attributes list.
+ * Read all VALUES into the dictionary_values list.
+ *
+ * @param rh a handle to parsed configuration.
+ * @param filename the name of the dictionary file.
+ * @return 0 on success, -1 on failure.
+ */
+int rc_read_dictionary (rc_handle *rh, char const *filename)
+{
+	FILE           *dictfd;
+	char            dummystr[AUTH_ID_LEN];
+	char            namestr[AUTH_ID_LEN];
+	char            valstr[AUTH_ID_LEN];
+	char            attrstr[AUTH_ID_LEN];
+	char            typestr[AUTH_ID_LEN];
+	char		optstr[AUTH_ID_LEN];
+	char		*cp, *ifilename;
+	int             line_no;
+	DICT_ATTR      *attr;
+	DICT_VALUE     *dval;
+	DICT_VENDOR    *dvend;
+	char            buffer[256];
+	int             value;
+	int             type;
+	unsigned attr_vendorspec = 0;
+
+	if ((dictfd = fopen (filename, "r")) == NULL)
+	{
+		rc_log(LOG_ERR, "rc_read_dictionary couldn't open dictionary %s: %s",
+				filename, strerror(errno));
+		return -1;
+	}
+
+	line_no = 0;
+	while (fgets (buffer, sizeof (buffer), dictfd) != NULL)
+	{
+		line_no++;
+
+		/* Skip empty space */
+		if (*buffer == '#' || *buffer == '\0' || *buffer == '\n' || \
+		    *buffer == '\r')
+		{
+			continue;
+		}
+
+		/* Strip out comments */
+		cp = strchr(buffer, '#');
+		if (cp != NULL)
+		{
+			*cp = '\0';
+		}
+
+		if (strncmp (buffer, "ATTRIBUTE", 9) == 0)
+		{
+			optstr[0] = '\0';
+			/* Read the ATTRIBUTE line */
+			if (sscanf (buffer, "%63s%63s%63s%63s%63s", dummystr, namestr,
+				    valstr, typestr, optstr) < 4)
+			{
+				rc_log(LOG_ERR, "rc_read_dictionary: invalid attribute on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+
+			/*
+			 * Validate all entries
+			 */
+			if (strlen (namestr) > NAME_LENGTH)
+			{
+				rc_log(LOG_ERR, "rc_read_dictionary: invalid name length on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+
+			if (!isdigit (*valstr))
+			{
+				rc_log(LOG_ERR,
+				 "rc_read_dictionary: invalid value on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+			value = atoi (valstr);
+
+			if (strcmp (typestr, "string") == 0)
+			{
+				type = PW_TYPE_STRING;
+			}
+			else if (strcmp (typestr, "integer") == 0)
+			{
+				type = PW_TYPE_INTEGER;
+			}
+			else if (strcmp (typestr, "ipaddr") == 0)
+			{
+				type = PW_TYPE_IPADDR;
+			}
+			else if (strcmp (typestr, "ipv6addr") == 0)
+			{
+				type = PW_TYPE_IPV6ADDR;
+			}
+			else if (strcmp (typestr, "ipv6prefix") == 0)
+			{
+				type = PW_TYPE_IPV6PREFIX;
+			}
+			else if (strcmp (typestr, "date") == 0)
+			{
+				type = PW_TYPE_DATE;
+			}
+			else
+			{
+				rc_log(LOG_ERR,
+				  "rc_read_dictionary: invalid type on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+
+			dvend = NULL;
+			if (optstr[0] != '\0') {
+				char *cp1;
+				for (cp1 = optstr; cp1 != NULL; cp1 = cp) {
+					cp = strchr(cp1, ',');
+					if (cp != NULL) {
+						*cp = '\0';
+						cp++;
+					}
+					if (strncmp(cp1, "vendor=", 7) == 0)
+						cp1 += 7;
+					dvend = rc_dict_findvend(rh, cp1);
+					if (dvend == NULL) {
+						rc_log(LOG_ERR,
+						 "rc_read_dictionary: unknown Vendor-Id %s on line %d of dictionary %s",
+							 cp1, line_no, filename);
+						fclose(dictfd);
+						return -1;
+					}
+				}
+			}
+
+			/* Create a new attribute for the list */
+			if ((attr = malloc (sizeof (DICT_ATTR))) == NULL)
+			{
+				rc_log(LOG_CRIT, "rc_read_dictionary: out of memory");
+				fclose(dictfd);
+				return -1;
+			}
+			strcpy (attr->name, namestr);
+			attr->value = value | (attr_vendorspec << 16);
+			attr->type = type;
+
+			if (dvend != NULL) {
+				attr->value = value | (dvend->vendorpec << 16);
+			} else {
+				attr->value = value | (attr_vendorspec << 16);
+			}
+
+			/* Insert it into the list */
+			attr->next = rh->dictionary_attributes;
+			rh->dictionary_attributes = attr;
+		}
+		else if (strncmp (buffer, "VALUE", 5) == 0)
+		{
+			/* Read the VALUE line */
+			if (sscanf (buffer, "%63s%63s%63s%63s", dummystr, attrstr,
+				    namestr, valstr) != 4)
+			{
+				rc_log(LOG_ERR,
+			   "rc_read_dictionary: invalid value entry on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+
+			/*
+			 * Validate all entries
+			 */
+			if (strlen (attrstr) > NAME_LENGTH)
+			{
+				rc_log(LOG_ERR,
+		      "rc_read_dictionary: invalid attribute length on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+
+			if (strlen (namestr) > NAME_LENGTH)
+			{
+				rc_log(LOG_ERR,
+			   "rc_read_dictionary: invalid name length on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+
+			if (!isdigit (*valstr))
+			{
+				rc_log(LOG_ERR,
+				 "rc_read_dictionary: invalid value on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+			value = atoi (valstr);
+
+			/* Create a new VALUE entry for the list */
+			if ((dval = malloc (sizeof (DICT_VALUE))) == NULL)
+			{
+				rc_log(LOG_CRIT, "rc_read_dictionary: out of memory");
+				fclose(dictfd);
+				return -1;
+			}
+			strcpy (dval->attrname, attrstr);
+			strcpy (dval->name, namestr);
+			dval->value = value;
+
+			/* Insert it into the list */
+			dval->next = rh->dictionary_values;
+			rh->dictionary_values = dval;
+		}
+                else if (strncmp (buffer, "$INCLUDE", 8) == 0)
+                {
+			/* Read the $INCLUDE line */
+			if (sscanf (buffer, "%63s%63s", dummystr, namestr) != 2)
+			{
+				rc_log(LOG_ERR,
+				 "rc_read_dictionary: invalid include entry on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+			ifilename = namestr;
+			/* Append directory if necessary */
+			if (namestr[0] != '/') {
+				cp = strrchr(filename, '/');
+				if (cp != NULL) {
+					ifilename = malloc(AUTH_ID_LEN);
+					*cp = '\0';
+					snprintf(ifilename, AUTH_ID_LEN, "%s/%s", filename, namestr);
+					*cp = '/';
+				}
+			}
+			if (rc_read_dictionary(rh, ifilename) < 0)
+			{
+				fclose(dictfd);
+				return -1;
+			}
+		}
+		else if (strncmp (buffer, "END-VENDOR", 10) == 0)
+		{
+			attr_vendorspec = 0;
+		}
+		else if (strncmp (buffer, "BEGIN-VENDOR", 12) == 0)
+		{
+			DICT_VENDOR *v;
+			/* Read the vendor name */
+			if (sscanf (buffer+12, "%63s", dummystr) != 1)
+			{
+				rc_log(LOG_ERR,
+				 "rc_read_dictionary: invalid Vendor-Id on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+
+			v = rc_dict_findvend(rh, dummystr);
+			if (v == NULL) {
+				rc_log(LOG_ERR,
+				 "rc_read_dictionary: unknown Vendor %s on line %d of dictionary %s",
+					 dummystr, line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+
+			attr_vendorspec = v->vendorpec;
+		}
+		else if (strncmp (buffer, "VENDOR", 6) == 0)
+		{
+			/* Read the VALUE line */
+			if (sscanf (buffer, "%63s%63s%63s", dummystr, attrstr, valstr) != 3)
+			{
+				rc_log(LOG_ERR,
+				 "rc_read_dictionary: invalid Vendor-Id on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+
+			/* Validate all entries */
+			if (strlen (attrstr) > NAME_LENGTH)
+			{
+				rc_log(LOG_ERR,
+				 "rc_read_dictionary: invalid attribute length on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+
+			if (!isdigit (*valstr))
+			{
+				rc_log(LOG_ERR,
+				 "rc_read_dictionary: invalid Vendor-Id on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+			value = atoi (valstr);
+
+			/* Create a new VENDOR entry for the list */
+			dvend = malloc(sizeof(DICT_VENDOR));
+			if (dvend == NULL)
+			{
+				rc_log(LOG_CRIT, "rc_read_dictionary: out of memory");
+				fclose(dictfd);
+				return -1;
+			}
+			strcpy (dvend->vendorname, attrstr);
+			dvend->vendorpec = value;
+
+			/* Insert it into the list */
+			dvend->next = rh->dictionary_vendors;
+			rh->dictionary_vendors = dvend;
+                }
+	}
+	fclose (dictfd);
+	return 0;
+}
+
+/** Lookup a DICT_ATTR by attribute number
+ *
+ * @param rh a handle to parsed configuration.
+ * @param attribute the attribute ID.
+ * @return the full attribute structure based on the attribute id number.
+ */
+DICT_ATTR *rc_dict_getattr(rc_handle const *rh, int attribute)
+{
+	DICT_ATTR      *attr;
+
+	attr = rh->dictionary_attributes;
+	while (attr != NULL)
+	{
+		if (attr->value == attribute)
+		{
+			return attr;
+		}
+		attr = attr->next;
+	}
+	return NULL;
+}
+
+/** Lookup a DICT_ATTR by its name
+ *
+ * @param rh a handle to parsed configuration.
+ * @param attrname the attribute name.
+ *
+ * @return the full attribute structure based on the attribute name.
+ */
+DICT_ATTR *rc_dict_findattr(rc_handle const *rh, char const *attrname)
+{
+	DICT_ATTR      *attr;
+
+	attr = rh->dictionary_attributes;
+	while (attr != NULL)
+	{
+		if (strcasecmp (attr->name, attrname) == 0)
+		{
+			return attr;
+		}
+		attr = attr->next;
+	}
+	return NULL;
+}
+
+
+/** Lookup a DICT_VALUE by its name
+ *
+ * @param rh a handle to parsed configuration.
+ * @param valname the value name.
+ * @return the full value structure based on the value name.
+ */
+DICT_VALUE *rc_dict_findval(rc_handle const *rh, char const *valname)
+{
+	DICT_VALUE     *val;
+
+	val = rh->dictionary_values;
+	while (val != NULL)
+	{
+		if (strcasecmp (val->name, valname) == 0)
+		{
+			return val;
+		}
+		val = val->next;
+	}
+	return NULL;
+}
+
+/** Lookup a DICT_VENDOR by its name
+ *
+ * @param rh a handle to parsed configuration.
+ * @param valname the vendor name.
+ * @return the full vendor structure based on the vendor name.
+ */
+DICT_VENDOR *rc_dict_findvend(rc_handle const *rh, char const *vendorname)
+{
+	DICT_VENDOR	*vend;
+
+	for (vend = rh->dictionary_vendors; vend != NULL; vend = vend->next)
+		if (strcasecmp(vend->vendorname, vendorname) == 0)
+			return vend;
+	return NULL;
+}
+
+/** Lookup a DICT_VENDOR by its IANA number
+ *
+ * @param rh a handle to parsed configuration.
+ * @param vendorpec the vendor ID.
+ * @return the full vendor structure based on the vendor id number.
+ */
+DICT_VENDOR *rc_dict_getvend (rc_handle const *rh, int vendorpec)
+{
+        DICT_VENDOR      *vend;
+
+	for (vend = rh->dictionary_vendors; vend != NULL; vend = vend->next)
+		if (vend->vendorpec == vendorpec)
+			return vend;
+	return NULL;
+}
+
+/** Get DICT_VALUE based on attribute name and integer value number
+ *
+ * @param rh a handle to parsed configuration.
+ * @param value the attribute value.
+ * @param attrname the attribute name.
+ * @return the full value structure based on the actual value and the associated attribute name.
+ */
+DICT_VALUE *rc_dict_getval(rc_handle const *rh, uint32_t value, char const *attrname)
+{
+	DICT_VALUE     *val;
+
+	val = rh->dictionary_values;
+	while (val != NULL)
+	{
+		if (strcmp (val->attrname, attrname) == 0 &&
+				val->value == value)
+		{
+			return val;
+		}
+		val = val->next;
+	}
+	return NULL;
+}
+
+/** Frees the allocated av lists
+ *
+ * @param rh a handle to parsed configuration.
+ */
+void rc_dict_free(rc_handle *rh)
+{
+	DICT_ATTR	*attr, *nattr;
+	DICT_VALUE	*val, *nval;
+	DICT_VENDOR	*vend, *nvend;
+
+	for (attr = rh->dictionary_attributes; attr != NULL; attr = nattr) {
+		nattr = attr->next;
+		free(attr);
+	}
+	for (val = rh->dictionary_values; val != NULL; val = nval) {
+		nval = val->next;
+		free(val);
+	}
+	for (vend = rh->dictionary_vendors; vend != NULL; vend = nvend) {
+		nvend = vend->next;
+		free(vend);
+	}
+	rh->dictionary_attributes = NULL;
+	rh->dictionary_values = NULL;
+	rh->dictionary_vendors = NULL;
+}

+ 138 - 0
thirdparty/FreeRadius/lib/env.c

@@ -0,0 +1,138 @@
+/*
+ * $Id: env.c,v 1.6 2007/06/21 18:07:23 cparker Exp $
+ *
+ * Copyright (C) 1995,1996,1997 Lars Fenneberg
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+#include <config.h>
+#include <includes.h>
+#include <freeradius-client.h>
+
+/** Allocate space for a new environment
+ *
+ * @param size the maximum size of the environment.
+ * @return the initialized environment.
+ */
+ENV *rc_new_env(int size)
+{
+	ENV *p;
+
+	if (size < 1)
+		return NULL;
+
+	if ((p = malloc(sizeof(*p))) == NULL)
+		return NULL;
+
+	if ((p->env = malloc(size * sizeof(char *))) == NULL)
+	{
+		rc_log(LOG_CRIT, "rc_new_env: out of memory");
+		free(p);
+		return NULL;
+	}
+
+	p->env[0] = NULL;
+
+	p->size = 0;
+	p->maxsize = size;
+
+	return p;
+}
+
+/** Free the space used by an env structure
+ *
+ * @param env an initialized environment value.
+ */
+void rc_free_env(ENV *env)
+{
+	free(env->env);
+	free(env);
+}
+
+/** Add an environment entry
+ *
+ * @param env an initialized environment value.
+ * @return 0 on success or -1 on error.
+ */
+int rc_add_env(ENV *env, char const *name, char const *value)
+{
+	int i;
+	size_t len;
+	char *new_env;
+
+	for (i = 0; env->env[i] != NULL; i++)
+	{
+		if (strncmp(env->env[i], name, MAX(strchr(env->env[i], '=') - env->env[i], (int)strlen(name))) == 0)
+			break;
+	}
+
+	if (env->env[i])
+	{
+		len = strlen(name)+strlen(value)+2;
+		if ((new_env = realloc(env->env[i], len)) == NULL)
+			return -1;
+
+		env->env[i] = new_env;
+
+		snprintf(env->env[i], len, "%s=%s", name, value);
+	} else {
+		if (env->size == (env->maxsize-1)) {
+			rc_log(LOG_CRIT, "rc_add_env: not enough space for environment (increase ENV_SIZE)");
+			return -1;
+		}
+
+		len = strlen(name)+strlen(value)+2;
+		if ((env->env[env->size] = malloc(len)) == NULL) {
+			rc_log(LOG_CRIT, "rc_add_env: out of memory");
+			return -1;
+		}
+
+		snprintf(env->env[env->size], len, "%s=%s", name, value);
+
+		env->size++;
+
+		env->env[env->size] = NULL;
+	}
+
+	return 0;
+}
+
+/** Imports an array of null-terminated strings
+ *
+ * @param env an initialized environment value.
+ * @return 0 on success or -1 on error.
+ */
+int rc_import_env(ENV *env, char const **import)
+{
+	char *es;
+
+	while (*import)
+	{
+		es = strchr(*import, '=');
+
+		if (!es)
+		{
+			import++;
+			continue;
+		}
+
+		/* ok, i grant thats not very clean... */
+		*es = '\0';
+
+		if (rc_add_env(env, *import, es+1) < 0)
+		{
+			*es = '=';
+			return -1;
+		}
+
+		*es = '=';
+
+		import++;
+	}
+
+	return 0;
+}

+ 49 - 0
thirdparty/FreeRadius/lib/fr_log.c

@@ -0,0 +1,49 @@
+/*
+ * $Id: log.c,v 1.5 2007/06/21 18:07:23 cparker Exp $
+ *
+ * Copyright (C) 1995,1996,1997 Lars Fenneberg
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+#include <radius_config.h>
+#include <includes.h>
+#include <freeradius-client.h>
+
+/** Opens system log
+ *
+ * @param ident the name of the program.
+ */
+void rc_openlog(char const *ident)
+{
+#ifndef _MSC_VER /* TODO: Fix me */
+//	openlog(ident, LOG_PID, RC_LOG_FACILITY);
+#endif
+}
+
+/** Logs information on system log
+ *
+ * @param prio the syslog priority.
+ * @param format the format of the data to print.
+ */
+void rc_log(int prio, char const *format, ...)
+{
+#ifdef RC_LOG  
+    printf(format);
+#endif    
+/*  
+	char buff[1024];
+	va_list ap;
+
+	va_start(ap,format);
+	vsnprintf(buff, sizeof(buff), format, ap);
+	va_end(ap);
+
+#ifndef _MSC_VER  TODO: Fix me 
+	syslog(prio, "%s", buff);
+#endif
+*/    
+}

+ 251 - 0
thirdparty/FreeRadius/lib/fr_md5.c

@@ -0,0 +1,251 @@
+#include "fr_md5.h"
+
+/*	The below was retrieved from
+ *	http://www.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/crypto/md5.c?rev=1.1
+ *	with the following changes:
+ *	#includes commented out.
+ *	Support context->count as uint32_t[2] instead of uint64_t
+ *	u_int* to uint*
+ */
+
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest.	This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+/*#include <sys/param.h>*/
+/*#include <sys/systm.h>*/
+/*#include <crypto/md5.h>*/
+
+#define PUT_64BIT_LE(cp, value) do {				\
+	(cp)[7] = (value)[1] >> 24;					\
+	(cp)[6] = (value)[1] >> 16;					\
+	(cp)[5] = (value)[1] >> 8;					\
+	(cp)[4] = (value)[1];						\
+	(cp)[3] = (value)[0] >> 24;					\
+	(cp)[2] = (value)[0] >> 16;					\
+	(cp)[1] = (value)[0] >> 8;					\
+	(cp)[0] = (value)[0]; } while (0)
+
+#define PUT_32BIT_LE(cp, value) do {					\
+	(cp)[3] = (value) >> 24;					\
+	(cp)[2] = (value) >> 16;					\
+	(cp)[1] = (value) >> 8;						\
+	(cp)[0] = (value); } while (0)
+
+static uint8_t PADDING[MD5_BLOCK_LENGTH] = {
+	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*
+ * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void
+MD5Init(MD5_CTX *ctx)
+{
+	ctx->count[0] = 0;
+	ctx->count[1] = 0;
+	ctx->state[0] = 0x67452301;
+	ctx->state[1] = 0xefcdab89;
+	ctx->state[2] = 0x98badcfe;
+	ctx->state[3] = 0x10325476;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+MD5Update(MD5_CTX *ctx, uint8_t const *input, size_t len)
+{
+	size_t have, need;
+
+	/* Check how many bytes we already have and how many more we need. */
+	have = (size_t)((ctx->count[0] >> 3) & (MD5_BLOCK_LENGTH - 1));
+	need = MD5_BLOCK_LENGTH - have;
+
+	/* Update bitcount */
+/*	ctx->count += (uint64_t)len << 3;*/
+	if ((ctx->count[0] += ((uint32_t)len << 3)) < (uint32_t)len) {
+	/* Overflowed ctx->count[0] */
+		ctx->count[1]++;
+	}
+	ctx->count[1] += ((uint32_t)len >> 29);
+
+
+
+	if (len >= need) {
+		if (have != 0) {
+			memcpy(ctx->buffer + have, input, need);
+			MD5Transform(ctx->state, ctx->buffer);
+			input += need;
+			len -= need;
+			have = 0;
+		}
+
+		/* Process data in MD5_BLOCK_LENGTH-byte chunks. */
+		while (len >= MD5_BLOCK_LENGTH) {
+			MD5Transform(ctx->state, input);
+			input += MD5_BLOCK_LENGTH;
+			len -= MD5_BLOCK_LENGTH;
+		}
+	}
+
+	/* Handle any remaining bytes of data. */
+	if (len != 0)
+		memcpy(ctx->buffer + have, input, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void
+MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx)
+{
+	uint8_t count[8];
+	size_t padlen;
+	int i;
+
+	/* Convert count to 8 bytes in little endian order. */
+	PUT_64BIT_LE(count, ctx->count);
+
+	/* Pad out to 56 mod 64. */
+	padlen = MD5_BLOCK_LENGTH -
+	    ((ctx->count[0] >> 3) & (MD5_BLOCK_LENGTH - 1));
+	if (padlen < 1 + 8)
+		padlen += MD5_BLOCK_LENGTH;
+	MD5Update(ctx, PADDING, padlen - 8);		/* padlen - 8 <= 64 */
+	MD5Update(ctx, count, 8);
+
+	if (digest != NULL) {
+		for (i = 0; i < 4; i++)
+			PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
+	}
+	memset(ctx, 0, sizeof(*ctx));	/* in case it's sensitive */
+}
+
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+	( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data.  MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void
+MD5Transform(uint32_t state[4], uint8_t const block[MD5_BLOCK_LENGTH])
+{
+	uint32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4];
+
+	for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) {
+		in[a] = (uint32_t)(
+		    (uint32_t)(block[a * 4 + 0]) |
+		    (uint32_t)(block[a * 4 + 1]) <<  8 |
+		    (uint32_t)(block[a * 4 + 2]) << 16 |
+		    (uint32_t)(block[a * 4 + 3]) << 24);
+	}
+
+	a = state[0];
+	b = state[1];
+	c = state[2];
+	d = state[3];
+
+	MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478,  7);
+	MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12);
+	MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17);
+	MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22);
+	MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf,  7);
+	MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12);
+	MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17);
+	MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22);
+	MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8,  7);
+	MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12);
+	MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+	MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+	MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122,  7);
+	MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+	MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+	MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+	MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562,  5);
+	MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340,  9);
+	MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+	MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20);
+	MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d,  5);
+	MD5STEP(F2, d, a, b, c, in[10] + 0x02441453,  9);
+	MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+	MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20);
+	MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6,  5);
+	MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6,  9);
+	MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14);
+	MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20);
+	MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905,  5);
+	MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8,  9);
+	MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14);
+	MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+	MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942,  4);
+	MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11);
+	MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+	MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+	MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44,  4);
+	MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11);
+	MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16);
+	MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+	MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6,  4);
+	MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11);
+	MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16);
+	MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23);
+	MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039,  4);
+	MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+	MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+	MD5STEP(F3, b, c, d, a, in[2 ] + 0xc4ac5665, 23);
+
+	MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244,  6);
+	MD5STEP(F4, d, a, b, c, in[7 ] + 0x432aff97, 10);
+	MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+	MD5STEP(F4, b, c, d, a, in[5 ] + 0xfc93a039, 21);
+	MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3,  6);
+	MD5STEP(F4, d, a, b, c, in[3 ] + 0x8f0ccc92, 10);
+	MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+	MD5STEP(F4, b, c, d, a, in[1 ] + 0x85845dd1, 21);
+	MD5STEP(F4, a, b, c, d, in[8 ] + 0x6fa87e4f,  6);
+	MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+	MD5STEP(F4, c, d, a, b, in[6 ] + 0xa3014314, 15);
+	MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+	MD5STEP(F4, a, b, c, d, in[4 ] + 0xf7537e82,  6);
+	MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+	MD5STEP(F4, c, d, a, b, in[2 ] + 0x2ad7d2bb, 15);
+	MD5STEP(F4, b, c, d, a, in[9 ] + 0xeb86d391, 21);
+
+	state[0] += a;
+	state[1] += b;
+	state[2] += c;
+	state[3] += d;
+}

+ 86 - 0
thirdparty/FreeRadius/lib/fr_md5.h

@@ -0,0 +1,86 @@
+/*
+ * md5.h        Structures and prototypes for md5.
+ *
+ * Version:     $Id: md5.h,v 1.2 2007/06/21 18:07:24 cparker Exp $
+ * License:	BSD, but largely derived from a public domain source.
+ *
+ */
+
+#ifndef _RCRAD_MD5_H
+#define _RCRAD_MD5_H
+
+#include "radius_config.h"
+
+#ifdef HAVE_NETTLE
+
+#include <nettle/md5-compat.h>
+
+#else
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#include <string.h>
+/*
+ *  FreeRADIUS Client defines to ensure globally unique MD5 function names,
+ *  so that we don't pick up vendor-specific broken MD5 libraries.
+ */
+#define MD5_CTX		librad_MD5_CTX
+#define MD5Init		librad_MD5Init
+#define MD5Update	librad_MD5Update
+#define MD5Final	librad_MD5Final
+#define MD5Transform	librad_MD5Transform
+
+/*  The below was retrieved from
+ *  http://www.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/crypto/md5.h?rev=1.1
+ *  With the following changes: uint64_t => uint32_t[2]
+ *  Commented out #include <sys/cdefs.h>
+ *  Commented out the __BEGIN and __END _DECLS, and the __attributes.
+ */
+
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest.  This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ */
+
+#define	MD5_BLOCK_LENGTH		64
+#define	MD5_DIGEST_LENGTH		16
+
+typedef struct MD5Context {
+	uint32_t state[4];			//!< State.
+	uint32_t count[2];			//!< Number of bits, mod 2^64.
+	uint8_t buffer[MD5_BLOCK_LENGTH];	//!< Input buffer.
+} MD5_CTX;
+
+/* include <sys/cdefs.h> */
+
+/* __BEGIN_DECLS */
+void	 MD5Init(MD5_CTX *);
+void	 MD5Update(MD5_CTX *, uint8_t const *, size_t)
+/*		__attribute__((__bounded__(__string__,2,3)))*/;
+void	 MD5Final(uint8_t [MD5_DIGEST_LENGTH], MD5_CTX *)
+/*		__attribute__((__bounded__(__minbytes__,1,MD5_DIGEST_LENGTH)))*/;
+void	 MD5Transform(uint32_t [4], uint8_t const [MD5_BLOCK_LENGTH])
+/*		__attribute__((__bounded__(__minbytes__,1,4)))*/
+/*		__attribute__((__bounded__(__minbytes__,2,MD5_BLOCK_LENGTH)))*/;
+/* __END_DECLS */
+
+#endif /* HAVE_NETTLE */
+
+#endif /* _RCRAD_MD5_H */

+ 56 - 0
thirdparty/FreeRadius/lib/fr_options.h

@@ -0,0 +1,56 @@
+/*
+ * $Id: options.h,v 1.6 2008/03/05 16:35:20 cparker Exp $
+ *
+ * Copyright (C) 1996 Lars Fenneberg
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+#define OPTION_LEN	64
+
+/* ids for different option types */
+#define OT_STR		(1<<0)			//!< string.
+#define OT_INT		(1<<1)			//!< integer.
+#define OT_SRV		(1<<2)			//!< server list.
+#define OT_AUO		(1<<3)			//!< authentication order.
+
+#define OT_ANY		((unsigned int)~0)	//!< Used internally.
+
+/* status types */
+#define ST_UNDEF	(1<<0)			//!< option is undefined.
+
+typedef struct _option {
+	char name[OPTION_LEN];			//!< name of the option.
+	int type, status;			//!< type and status.
+	void *val;				//!< pointer to option value.
+} OPTION;
+
+static OPTION config_options_default[] = {
+/* internally used options */
+{"config_file",		OT_STR, ST_UNDEF, NULL},
+/* General options */
+{"auth_order",	 	OT_AUO, ST_UNDEF, NULL},
+{"login_tries",	 	OT_INT, ST_UNDEF, NULL},
+{"login_timeout",	OT_INT, ST_UNDEF, NULL},
+{"nologin",		OT_STR, ST_UNDEF, NULL},
+{"issue",		OT_STR, ST_UNDEF, NULL},
+/* RADIUS specific options */
+{"authserver",		OT_SRV, ST_UNDEF, NULL},
+{"acctserver",		OT_SRV, ST_UNDEF, NULL},
+{"servers",		OT_STR, ST_UNDEF, NULL},
+{"dictionary",		OT_STR, ST_UNDEF, NULL},
+{"login_radius",	OT_STR, ST_UNDEF, NULL},
+{"mapfile",		OT_STR, ST_UNDEF, NULL},
+{"default_realm",	OT_STR, ST_UNDEF, NULL},
+{"radius_timeout",	OT_INT, ST_UNDEF, NULL},
+{"radius_retries",	OT_INT,	ST_UNDEF, NULL},
+{"radius_deadtime",	OT_INT, ST_UNDEF, NULL},
+{"bindaddr",		OT_STR, ST_UNDEF, NULL},
+/* local options */
+{"login_local",		OT_STR, ST_UNDEF, NULL},
+};
+
+#define	NUM_OPTIONS	((sizeof(config_options_default))/(sizeof(config_options_default[0])))

+ 184 - 0
thirdparty/FreeRadius/lib/ip_util.c

@@ -0,0 +1,184 @@
+/*
+ * $Id: ip_util.c,v 1.14 2010/03/17 18:57:01 aland Exp $
+ *
+ * Copyright (C) 1995,1996,1997 Lars Fenneberg
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ *
+ * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
+ * and Merit Network, Inc. All Rights Reserved
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+#include <config.h>
+#include <includes.h>
+#include <freeradius-client.h>
+#include "util.h"
+
+#define HOSTBUF_SIZE 1024
+
+ /** Return a struct addrinfo from a host name or address in textual notation.
+  * @param host the name of the host
+  * @param flags should be a combinations of %PW_AI flags
+  * @return address which should be deallocated using freeaddrinfo() or NULL on failure
+  **/
+ 
+struct addrinfo *rc_getaddrinfo (char const *host, unsigned flags)
+ {
+	struct addrinfo hints, *res;
+	int err;
+	const char *service = NULL;
+ 
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_socktype = SOCK_DGRAM;
+	if (flags & PW_AI_PASSIVE)
+		hints.ai_flags = AI_PASSIVE;
+
+	if (flags & PW_AI_AUTH)
+		service = "radius";
+	else if (flags & PW_AI_ACCT)
+		service = "radius-acct";
+ 
+	err = getaddrinfo(host, service, &hints, &res);
+	if (err != 0) {
+ 		return NULL;
+ 	}
+
+	return res;
+}
+
+/** Get the port number for the supplied request type
+ *
+ * @param type %AUTH or %ACCT.
+ * @return the port number.
+ */
+unsigned short rc_getport(int type)
+{
+	struct servent *svp;
+
+	if ((svp = getservbyname ((type==AUTH)?"radius" : "radacct", "udp")) == NULL)
+	{
+		return (type==AUTH) ? PW_AUTH_UDP_PORT : PW_ACCT_UDP_PORT;
+	} else {
+		return ntohs ((unsigned short) svp->s_port);
+	}
+}
+
+/** Get the hostname of this machine
+ *
+ * @param hostname will hold the name of the host.
+ * @param len the size of hostname.
+ * @return -1 on failure, 0 on success.
+ */
+int
+rc_own_hostname(char *hostname, int len)
+{
+#ifdef HAVE_UNAME
+	struct	utsname uts;
+#endif
+
+#if defined(HAVE_UNAME)
+	if (uname(&uts) < 0)
+	{
+		rc_log(LOG_ERR,"rc_own_hostname: couldn't get own hostname");
+		return -1;
+	}
+	strlcpy(hostname, uts.nodename, len);
+#elif defined(HAVE_GETHOSTNAME)
+	if (gethostname(hostname, len) < 0)
+	{
+		rc_log(LOG_ERR,"rc_own_hostname: couldn't get own hostname");
+		return -1;
+	}
+#elif defined(HAVE_SYSINFO)
+	if (sysinfo(SI_HOSTNAME, hostname, len) < 0)
+	{
+		rc_log(LOG_ERR,"rc_own_hostname: couldn't get own hostname");
+		return -1;
+	}
+#else
+	return -1;
+#endif
+
+	return 0;
+}
+
+/** Find outbound interface address for a given destination
+ *
+ * Given remote address find local address which the system will use as a source address for sending
+ * datagrams to that remote address.
+ *
+ * @param lia local address.
+ * @param ria the remove address.
+ * @return 0 in success, -1 on failure, address is filled into the first argument.
+ */
+int rc_get_srcaddr(struct sockaddr *lia, const struct sockaddr *ria)
+{
+	int temp_sock;
+	socklen_t namelen;
+
+	temp_sock = socket(ria->sa_family, SOCK_DGRAM, 0);
+	if (temp_sock == -1) {
+		rc_log(LOG_ERR, "rc_get_srcaddr: socket: %s", strerror(errno));
+		return -1;
+	}
+
+	if (connect(temp_sock, ria, SA_LEN(ria)) != 0) {
+		rc_log(LOG_ERR, "rc_get_srcaddr: connect: %s",
+		    strerror(errno));
+		close(temp_sock);
+		return -1;
+	}
+
+	namelen = SA_LEN(ria);
+	if (getsockname(temp_sock, lia, &namelen) != 0) {
+		rc_log(LOG_ERR, "rc_get_srcaddr: getsockname: %s",
+		    strerror(errno));
+		close(temp_sock);
+		return -1;
+	}
+
+	close(temp_sock);
+	return 0;
+}
+
+/** rc_own_bind_addr:
+ * @rh: a handle to parsed configuration
+ * @lia: the local address to listen to
+ *
+ * Get the IP address to be used as a source address
+ * for sending requests in host order.
+ *
+ **/
+void rc_own_bind_addr(rc_handle *rh, struct sockaddr_storage *lia)
+{
+	char *txtaddr = rc_conf_str(rh, "bindaddr");
+	struct addrinfo *info;
+
+	if (rh->own_bind_addr_set) {
+		memcpy(lia, &rh->own_bind_addr, SS_LEN(&rh->own_bind_addr));
+		return;
+	}
+
+	memset(lia, 0, sizeof(*lia));
+	if (txtaddr == NULL || txtaddr[0] == '*') {
+		((struct sockaddr_in*)lia)->sin_family = AF_INET;
+		((struct sockaddr_in*)lia)->sin_addr.s_addr = INADDR_ANY;
+	} else {
+		info = rc_getaddrinfo (txtaddr, PW_AI_PASSIVE);
+		if (info == NULL) {
+			rc_log(LOG_ERR, "rc_own_ipaddress: couldn't get IP address from bindaddr");
+			((struct sockaddr_in*)lia)->sin_family = AF_INET;
+			((struct sockaddr_in*)lia)->sin_addr.s_addr = INADDR_ANY;
+			return;
+		}
+
+		memcpy(lia, info->ai_addr, info->ai_addrlen);
+       }
+
+       return;
+}

+ 29 - 0
thirdparty/FreeRadius/lib/rc-md5.c

@@ -0,0 +1,29 @@
+/* MD5 message-digest algorithm */
+
+/* This file is licensed under the BSD License, but is largely derived from
+ * public domain source code
+ */
+
+/*
+ *  FORCE MD5 TO USE OUR MD5 HEADER FILE!
+ *
+ *  If we don't do this, it might pick up the systems broken MD5.
+ */
+#include "rc-md5.h"
+
+/** Hash the provided data using MD5
+ *
+ * @param[out] output will hold a 16-byte checksum.
+ * @param[in] input pointer to data to hash.
+ * @param[in] inlen the length of input.
+ */
+void rc_md5_calc(unsigned char *output, unsigned char const *input,
+		 size_t inlen)
+{
+	MD5_CTX	context;
+
+	MD5Init(&context);
+	MD5Update(&context, input, inlen);
+	MD5Final(output, &context);
+}
+

+ 28 - 0
thirdparty/FreeRadius/lib/rc-md5.h

@@ -0,0 +1,28 @@
+/*
+ * md5.h        Structures and prototypes for md5.
+ *
+ * Version:     $Id: md5.h,v 1.2 2007/06/21 18:07:24 cparker Exp $
+ * License:	BSD
+ *
+ */
+
+#ifndef _RC_MD5_H
+#define _RC_MD5_H
+
+#include "radius_config.h"
+#include <stdlib.h>
+
+#ifdef HAVE_NETTLE
+
+#include <nettle/md5-compat.h>
+
+#else
+
+#include "fr_md5.h"
+
+#endif /* HAVE_NETTLE */
+
+void rc_md5_calc(unsigned char *output, unsigned char const *input,
+		     size_t inputlen);
+
+#endif /* _RC_MD5_H */

+ 863 - 0
thirdparty/FreeRadius/lib/sendserver.c

@@ -0,0 +1,863 @@
+/*
+ * $Id: sendserver.c,v 1.30 2010/06/15 09:22:52 aland Exp $
+ *
+ * Copyright (C) 1995,1996,1997 Lars Fenneberg
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ *
+ * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
+ * and Merit Network, Inc. All Rights Reserved
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+//#include <poll.h>
+
+#include <radius_config.h>
+#include <includes.h>
+#include <freeradius-client.h>
+#include <pathnames.h>
+#include "util.h"
+#include "radius_user.h"
+
+#include "lwip/sockets.h"
+
+#define	SA(p)	((struct sockaddr *)(p))
+
+static void rc_random_vector (unsigned char *);
+static int rc_check_reply (AUTH_HDR *, int, char const *, unsigned char const *, unsigned char);
+
+/** Packs an attribute value pair list into a buffer
+ *
+ * @param vp a pointer to a #VALUE_PAIR.
+ * @param secret the secret used by the server.
+ * @param auth a pointer to #AUTH_HDR.
+ * @return The number of octets packed.
+ */
+static int rc_pack_list (VALUE_PAIR *vp, char *secret, AUTH_HDR *auth)
+{
+	int             length, i, pc, padded_length;
+	int             total_length = 0;
+	size_t			secretlen;
+	uint32_t           lvalue, vendor;
+	unsigned char   passbuf[MAX(AUTH_PASS_LEN, CHAP_VALUE_LENGTH)];
+	unsigned char   md5buf[256];
+	unsigned char   *buf, *vector, *vsa_length_ptr;
+
+	buf = auth->data;
+
+	while (vp != NULL)
+	{
+		vsa_length_ptr = NULL;
+		if (VENDOR(vp->attribute) != 0) {
+			*buf++ = PW_VENDOR_SPECIFIC;
+			vsa_length_ptr = buf;
+			*buf++ = 6;
+			vendor = htonl(VENDOR(vp->attribute));
+			memcpy(buf, &vendor, sizeof(uint32_t));
+			buf += 4;
+			total_length += 6;
+		}
+		*buf++ = (vp->attribute & 0xff);
+
+		switch (vp->attribute)
+		{
+		 case PW_USER_PASSWORD:
+
+		  /* Encrypt the password */
+
+		  /* Chop off password at AUTH_PASS_LEN */
+		  length = vp->lvalue;
+		  if (length > AUTH_PASS_LEN)
+			length = AUTH_PASS_LEN;
+
+		  /* Calculate the padded length */
+		  padded_length = (length+(AUTH_VECTOR_LEN-1)) & ~(AUTH_VECTOR_LEN-1);
+
+		  /* Record the attribute length */
+		  *buf++ = padded_length + 2;
+		  if (vsa_length_ptr != NULL) *vsa_length_ptr += padded_length + 2;
+
+		  /* Pad the password with zeros */
+		  memset ((char *) passbuf, '\0', AUTH_PASS_LEN);
+		  memcpy ((char *) passbuf, vp->strvalue, (size_t) length);
+
+		  secretlen = strlen (secret);
+		  vector = (unsigned char *)auth->vector;
+		  for(i = 0; i < padded_length; i += AUTH_VECTOR_LEN)
+		  {
+		  	/* Calculate the MD5 digest*/
+		  	strcpy ((char *) md5buf, secret);
+		  	memcpy ((char *) md5buf + secretlen, vector,
+		  		  AUTH_VECTOR_LEN);
+		  	rc_md5_calc (buf, md5buf, secretlen + AUTH_VECTOR_LEN);
+
+		        /* Remeber the start of the digest */
+		  	vector = buf;
+
+			/* Xor the password into the MD5 digest */
+			for (pc = i; pc < (i + AUTH_VECTOR_LEN); pc++)
+		  	{
+				*buf++ ^= passbuf[pc];
+		  	}
+		  }
+
+		  total_length += padded_length + 2;
+
+		  break;
+		 default:
+		  switch (vp->type)
+		  {
+		    case PW_TYPE_STRING:
+			length = vp->lvalue;
+			*buf++ = length + 2;
+			if (vsa_length_ptr != NULL) *vsa_length_ptr += length + 2;
+			memcpy (buf, vp->strvalue, (size_t) length);
+			buf += length;
+			total_length += length + 2;
+			break;
+
+		    case PW_TYPE_IPV6ADDR:
+			length = 16;
+			*buf++ = length + 2;
+			if (vsa_length_ptr != NULL) *vsa_length_ptr += length + 2;
+			memcpy (buf, vp->strvalue, (size_t) length);
+			buf += length;
+			total_length += length + 2;
+			break;
+
+		    case PW_TYPE_IPV6PREFIX:
+			length = vp->lvalue;
+			*buf++ = length + 2;
+			if (vsa_length_ptr != NULL) *vsa_length_ptr += length + 2;
+			memcpy (buf, vp->strvalue, (size_t) length);
+			buf += length;
+			total_length += length + 2;
+			break;
+
+		    case PW_TYPE_INTEGER:
+		    case PW_TYPE_IPADDR:
+		    case PW_TYPE_DATE:
+			*buf++ = sizeof (uint32_t) + 2;
+			if (vsa_length_ptr != NULL) *vsa_length_ptr += sizeof(uint32_t) + 2;
+			lvalue = htonl (vp->lvalue);
+			memcpy (buf, (char *) &lvalue, sizeof (uint32_t));
+			buf += sizeof (uint32_t);
+			total_length += sizeof (uint32_t) + 2;
+			break;
+
+		    default:
+			break;
+		  }
+		  break;
+		}
+		vp = vp->next;
+	}
+	return total_length;
+}
+
+/** Appends a string to the provided buffer
+ *
+ * @param dest the destination buffer.
+ * @param max_size the maximum size available in the destination buffer.
+ * @param pos the current position in the dest buffer; initially must be zero.
+ * @param src the source buffer to append.
+ */
+static void strappend(char *dest, unsigned max_size, int *pos, const char *src)
+{
+	unsigned len = strlen(src) + 1;
+
+	if (*pos == -1)
+		return;
+
+	if (len + *pos > max_size) {
+		*pos = -1;
+		return;
+	}
+
+	memcpy(&dest[*pos], src, len);
+	*pos += len-1;
+	return;
+}
+
+/** Sends a request to a RADIUS server and waits for the reply
+ *
+ * @param rh a handle to parsed configuration
+ * @param data a pointer to a #SEND_DATA structure
+ * @param msg must be an array of %PW_MAX_MSG_SIZE or %NULL; will contain the concatenation of
+ *	any %PW_REPLY_MESSAGE received.
+ * @param flags must be %AUTH or %ACCT
+ * @return %OK_RC (0) on success, %TIMEOUT_RC on timeout %REJECT_RC on acess reject, or negative
+ *	on failure as return value.
+ */
+
+#define RS_PORT_NUM 1812
+//#define RS_IP_ADDR "192.168.1.2"
+#define RS_IP_ADDR "192.168.14.234"
+
+#define DEVICE_PORT_NUM 1812
+//#define DEVICE_IP_ADDR "192.168.1.6"
+#define DEVICE_IP_ADDR "192.168.14.37"
+
+#define BUF_LEN    300
+
+static uint8_t send_buffer[BUF_LEN];
+static uint8_t recv_buffer[BUF_LEN];
+
+int rc_send_server (rc_handle *rh, SEND_DATA *data, char *msg, unsigned flags)
+{
+#if 1
+    struct sockaddr_in sa,ra;
+    int             socket;
+    fdsets          sets;
+    AUTH_HDR*       auth;
+    AUTH_HDR*       recv_auth;
+    unsigned char   vector[AUTH_VECTOR_LEN];
+    char            secret[MAX_SECRET_LENGTH + 1];
+    int             total_length;
+    int             sendLen, recvLen;
+    int             length;
+    int             pos;
+    uint8_t*        attr;
+    int             result = 0;
+    VALUE_PAIR*     vp;
+    
+  
+    initFdsets(&sets);
+    
+	if(data->secret != NULL) {
+		strlcpy(secret, data->secret, MAX_SECRET_LENGTH);
+    }
+
+    memset(&ra, 0, sizeof(struct sockaddr_in));
+    ra.sin_family = AF_INET;
+    ra.sin_addr.s_addr = inet_addr(RS_IP_ADDR);
+    ra.sin_port = htons(RS_PORT_NUM);
+    
+    socket = socket(PF_INET, SOCK_DGRAM, 0);
+    if ( socket < 0 )
+    {
+        printf("socket call failed");
+        return -1;
+    }
+    
+    // TODO bind?
+    
+    // Build a request  (PW_ACCESS_REQUEST)
+	auth = (AUTH_HDR *) send_buffer;
+	auth->code = data->code;
+	auth->id = data->seq_nbr;
+
+    rc_random_vector(vector);
+	memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);
+
+	total_length = rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN;
+
+	auth->length = htons ((unsigned short) total_length);
+	    
+    
+    // Bind socket
+    memset(&sa, 0, sizeof(struct sockaddr_in));
+    sa.sin_family = AF_INET;
+    sa.sin_addr.s_addr = inet_addr(DEVICE_IP_ADDR);
+    sa.sin_port = htons(DEVICE_PORT_NUM);
+    
+    if (bind(socket, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) == -1)
+    {
+        printf("Bind to Port Number %d ,IP address %s failed\n", DEVICE_PORT_NUM, DEVICE_IP_ADDR);
+        close(socket);
+        return 0;
+    }
+       
+    sendLen = sendto(socket, (char*)auth, total_length, 0, (struct sockaddr*)&ra, sizeof(ra));
+    if(sendLen < 0)
+    {
+        printf("send failed\n");
+        close(socket);
+        return 0;
+    }
+   
+    // Получение ответа, select
+    if (!recvSelect(&sets, &socket, 2000)) {
+        //timeCount = HAL_GetTick() - timeCount;
+        printf("SOCK recv timeout!\r\n");
+        close(socket);
+        return 0;
+    }
+    
+    // Данные можно принимать
+    socklen_t sl = sizeof(sa);
+    recvLen = recvfrom(socket, recv_buffer, BUF_LEN, 0, (struct sockaddr*)&ra, &sl);
+
+    recv_auth = (AUTH_HDR*)recv_buffer;
+    
+    // Проверки размера входящего сообщения
+    if (recvLen < AUTH_HDR_LEN || recvLen < ntohs(recv_auth->length)) {
+		printf("radius_server: reply is too short\r\n");
+		close(socket);
+        return 0;
+	}
+    
+    if (recvLen > ntohs(recv_auth->length)) 
+    {
+        recvLen = ntohs(recv_auth->length);
+    }
+    
+    // Verify that it's a valid RADIUS packet before doing ANYTHING with it.
+	attr = recv_buffer + AUTH_HDR_LEN;
+	while (attr < (recv_buffer + recvLen)) {
+		if (attr[0] == 0) {
+            printf("radius_server: attribute zero is invalid\r\n");
+            close(socket);
+            return 0;
+		}
+
+		if (attr[1] < 2) {
+            printf("radius_server: attribute length is too small\r\n");
+            close(socket);
+            return 0;
+		}
+
+		if ((attr + attr[1]) > (recv_buffer + recvLen)) {
+            printf("radius_server: attribute overflows the packet\r\n");
+            close(socket);
+            return 0;
+		}
+
+		attr += attr[1];
+	}
+    
+    
+    result = rc_check_reply (recv_auth, BUF_LEN, secret, vector, data->seq_nbr);
+    
+    length = ntohs(recv_auth->length)  - AUTH_HDR_LEN;
+	if (length > 0) {
+		data->receive_pairs = rc_avpair_gen(rh, NULL, recv_auth->data, length, 0);
+	} else {
+		data->receive_pairs = NULL;
+	}
+
+	if (result != OK_RC) {
+		return result;
+	}
+    
+    if (msg) {
+		*msg = '\0';
+		pos = 0;
+		vp = data->receive_pairs;
+		while (vp)
+		{
+			if ((vp = rc_avpair_get(vp, PW_REPLY_MESSAGE, 0)))
+			{
+				strappend(msg, PW_MAX_MSG_SIZE, &pos, vp->strvalue);
+				strappend(msg, PW_MAX_MSG_SIZE, &pos, "\n");
+				vp = vp->next;
+			}
+		}
+	}
+
+	if ((recv_auth->code == PW_ACCESS_ACCEPT) ||
+		(recv_auth->code == PW_PASSWORD_ACK) ||
+		(recv_auth->code == PW_ACCOUNTING_RESPONSE))
+	{
+		result = OK_RC;
+	}
+	else if ((recv_auth->code == PW_ACCESS_REJECT) ||
+		(recv_auth->code == PW_PASSWORD_REJECT))
+	{
+		result = REJECT_RC;
+	}
+	else
+	{
+		rc_log(LOG_ERR, "rc_send_server: received RADIUS server response neither ACCEPT nor REJECT, invalid");
+		result = BADRESP_RC;
+	}
+    
+    
+    
+    
+    printf("Radius server end communication\r\n");
+    close(socket);
+    return result;
+    
+	//getnameinfo(SA(&our_sockaddr), SS_LEN(&our_sockaddr), NULL, 0, our_addr_txt, sizeof(our_addr_txt), NI_NUMERICHOST);
+	//getnameinfo(auth_addr->ai_addr, auth_addr->ai_addrlen, NULL, 0, auth_addr_txt, sizeof(auth_addr_txt), NI_NUMERICHOST);
+
+    
+#endif    
+  
+#if 0
+	int             sockfd;
+	AUTH_HDR       *auth, *recv_auth;
+	char           *server_name;	/* Name of server to query */
+	struct sockaddr_storage our_sockaddr;
+	struct addrinfo *auth_addr = NULL;
+	socklen_t       salen;
+	int             result = 0;
+	int             total_length;
+	int             length, pos;
+	int             retry_max;
+	unsigned	    discover_local_ip;
+    size_t		    secretlen;
+	char            secret[MAX_SECRET_LENGTH + 1];
+	unsigned char   vector[AUTH_VECTOR_LEN];
+	uint8_t         recv_buffer[BUFFER_LEN];
+	uint8_t         send_buffer[BUFFER_LEN];
+	char		    our_addr_txt[50]; /* hold a text IP */
+	char		    auth_addr_txt[50]; /* hold a text IP */
+	uint8_t		    *attr;
+	int		        retries;
+	VALUE_PAIR 	    *vp;
+	//struct pollfd	pfd;
+	double		    start_time, timeout;
+
+    
+	server_name = data->server;
+	if (server_name == NULL || server_name[0] == '\0')
+		return ERROR_RC;
+
+	if(data->secret != NULL)
+	{
+		//strlcpy(secret, data->secret, MAX_SECRET_LENGTH);
+        memcpy(secret, data->secret, MAX_SECRET_LENGTH);
+	}
+  
+	if (rc_find_server_addr (rh, server_name, &auth_addr, secret, flags) != 0)
+	{
+		rc_log(LOG_ERR, "rc_send_server: unable to find server: %s", server_name);
+		return ERROR_RC;
+	}
+
+	rc_own_bind_addr(rh, &our_sockaddr);
+	discover_local_ip = 0;
+	if (our_sockaddr.ss_family == AF_INET) {
+		if (((struct sockaddr_in*)(&our_sockaddr))->sin_addr.s_addr == INADDR_ANY) {
+			discover_local_ip = 1;
+		}
+	}
+
+	DEBUG(LOG_ERR, "DEBUG: rc_send_server: creating socket to: %s", server_name);
+	if (discover_local_ip) {
+		result = rc_get_srcaddr(SA(&our_sockaddr), auth_addr->ai_addr);
+		if (result != 0) {
+			memset (secret, '\0', sizeof (secret));
+			rc_log(LOG_ERR, "rc_send_server: cannot figure our own address");
+			result = ERROR_RC;
+			goto cleanup;
+		}
+	}
+
+	sockfd = socket (our_sockaddr.ss_family, SOCK_DGRAM, 0);
+	if (sockfd < 0)
+	{
+		memset (secret, '\0', sizeof (secret));
+		rc_log(LOG_ERR, "rc_send_server: socket: %s", strerror(errno));
+		result = ERROR_RC;
+		goto cleanup;
+	}
+
+	if (our_sockaddr.ss_family == AF_INET)
+		((struct sockaddr_in*)&our_sockaddr)->sin_port = 0;
+	else
+		((struct sockaddr_in6*)&our_sockaddr)->sin6_port = 0;
+
+	if (bind(sockfd, SA(&our_sockaddr), SS_LEN(&our_sockaddr)) < 0)
+	{
+		close (sockfd);
+		memset (secret, '\0', sizeof (secret));
+		rc_log(LOG_ERR, "rc_send_server: bind: %s: %s", server_name, strerror(errno));
+		result = ERROR_RC;
+		goto cleanup;
+	}
+
+	retry_max = data->retries;	/* Max. numbers to try for reply */
+	retries = 0;			/* Init retry cnt for blocking call */
+
+	if (data->svc_port) {
+		if (our_sockaddr.ss_family == AF_INET)
+			((struct sockaddr_in*)auth_addr->ai_addr)->sin_port = htons ((unsigned short) data->svc_port);
+		else
+			((struct sockaddr_in6*)auth_addr->ai_addr)->sin6_port = htons ((unsigned short) data->svc_port);
+	}
+
+	/*
+	 * Fill in NAS-IP-Address (if needed)
+	 */
+	if (rc_avpair_get(data->send_pairs, PW_NAS_IP_ADDRESS, 0) == NULL &&
+	    rc_avpair_get(data->send_pairs, PW_NAS_IPV6_ADDRESS, 0) == NULL) {
+		if (our_sockaddr.ss_family == AF_INET) {
+			uint32_t ip;
+			ip = *((uint32_t*)(&((struct sockaddr_in*)&our_sockaddr)->sin_addr));
+			ip = ntohl(ip);
+
+			rc_avpair_add(rh, &(data->send_pairs), PW_NAS_IP_ADDRESS,
+			    &ip, 0, 0);
+		} else {
+			void *p;
+			p = &((struct sockaddr_in6*)&our_sockaddr)->sin6_addr;
+
+			rc_avpair_add(rh, &(data->send_pairs), PW_NAS_IPV6_ADDRESS,
+			    p, 0, 0);
+		}
+	}
+
+	/* Build a request */
+	auth = (AUTH_HDR *) send_buffer;
+	auth->code = data->code;
+	auth->id = data->seq_nbr;
+
+	if (data->code == PW_ACCOUNTING_REQUEST)
+	{
+		total_length = rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN;
+
+		auth->length = htons ((unsigned short) total_length);
+
+		memset((char *) auth->vector, 0, AUTH_VECTOR_LEN);
+		secretlen = strlen (secret);
+		memcpy ((char *) auth + total_length, secret, secretlen);
+		rc_md5_calc (vector, (unsigned char *) auth, total_length + secretlen);
+		memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);
+	}
+	else
+	{
+		rc_random_vector (vector);
+		memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);
+
+		total_length = rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN;
+
+		auth->length = htons ((unsigned short) total_length);
+	}
+
+	getnameinfo(SA(&our_sockaddr), SS_LEN(&our_sockaddr), NULL, 0, our_addr_txt, sizeof(our_addr_txt), NI_NUMERICHOST);
+	getnameinfo(auth_addr->ai_addr, auth_addr->ai_addrlen, NULL, 0, auth_addr_txt, sizeof(auth_addr_txt), NI_NUMERICHOST);
+
+	DEBUG(LOG_ERR, "DEBUG: local %s : 0, remote %s : %u\n", 
+	      our_addr_txt, auth_addr_txt, data->svc_port);
+
+	for (;;)
+	{
+		do {
+			result = sendto (sockfd, (char *) auth, (unsigned int)total_length, 
+				(int) 0, SA(auth_addr->ai_addr), auth_addr->ai_addrlen);
+		} while (result == -1 && errno == EINTR);
+		if (result == -1) {
+			rc_log(LOG_ERR, "%s: socket: %s", __FUNCTION__, strerror(errno));
+		}
+
+		pfd.fd = sockfd;
+		pfd.events = POLLIN;
+		pfd.revents = 0;
+		start_time = rc_getctime();
+		for (timeout = data->timeout; timeout > 0;
+		    timeout -= rc_getctime() - start_time) {
+			result = poll(&pfd, 1, timeout * 1000);
+			if (result != -1 || errno != EINTR)
+				break;
+		}
+		if (result == -1)
+		{
+			rc_log(LOG_ERR, "rc_send_server: poll: %s", strerror(errno));
+			memset (secret, '\0', sizeof (secret));
+			close (sockfd);
+			result = ERROR_RC;
+			goto cleanup;
+		}
+		if (result == 1 && (pfd.revents & POLLIN) != 0)
+			break;
+
+		/*
+		 * Timed out waiting for response.  Retry "retry_max" times
+		 * before giving up.  If retry_max = 0, don't retry at all.
+		 */
+		if (retries++ >= retry_max)
+		{
+			rc_log(LOG_ERR,
+				"rc_send_server: no reply from RADIUS server %s:%u",
+				 auth_addr_txt, data->svc_port);
+			close (sockfd);
+			memset (secret, '\0', sizeof (secret));
+			result = TIMEOUT_RC;
+			goto cleanup;
+		}
+	}
+	salen = auth_addr->ai_addrlen;
+	do {
+		length = recvfrom (sockfd, (char *) recv_buffer,
+				   (int) sizeof (recv_buffer),
+				   (int) 0, SA(auth_addr->ai_addr), &salen);
+	} while(length == -1 && errno == EINTR);
+
+	if (length <= 0)
+	{
+		rc_log(LOG_ERR, "rc_send_server: recvfrom: %s:%d: %s", server_name,\
+			 data->svc_port, strerror(errno));
+		close (sockfd);
+		memset (secret, '\0', sizeof (secret));
+		result = ERROR_RC;
+		goto cleanup;
+	}
+
+	recv_auth = (AUTH_HDR *)recv_buffer;
+
+	if (length < AUTH_HDR_LEN || length < ntohs(recv_auth->length)) {
+		rc_log(LOG_ERR, "rc_send_server: recvfrom: %s:%d: reply is too short",
+		    server_name, data->svc_port);
+		close(sockfd);
+		memset(secret, '\0', sizeof(secret));
+		result = ERROR_RC;
+		goto cleanup;
+	}
+
+	/*
+	 *	If UDP is larger than RADIUS, shorten it to RADIUS.
+	 */
+	if (length > ntohs(recv_auth->length)) length = ntohs(recv_auth->length);
+
+	/*
+	 *	Verify that it's a valid RADIUS packet before doing ANYTHING with it.
+	 */
+	attr = recv_buffer + AUTH_HDR_LEN;
+	while (attr < (recv_buffer + length)) {
+		if (attr[0] == 0) {
+			rc_log(LOG_ERR, "rc_send_server: recvfrom: %s:%d: attribute zero is invalid",
+			       server_name, data->svc_port);
+			close(sockfd);
+			memset(secret, '\0', sizeof(secret));
+			return ERROR_RC;
+		}
+
+		if (attr[1] < 2) {
+			rc_log(LOG_ERR, "rc_send_server: recvfrom: %s:%d: attribute length is too small",
+			       server_name, data->svc_port);
+			close(sockfd);
+			memset(secret, '\0', sizeof(secret));
+			return ERROR_RC;
+		}
+
+		if ((attr + attr[1]) > (recv_buffer + length)) {
+			rc_log(LOG_ERR, "rc_send_server: recvfrom: %s:%d: attribute overflows the packet",
+			       server_name, data->svc_port);
+			close(sockfd);
+			memset(secret, '\0', sizeof(secret));
+			return ERROR_RC;
+		}
+
+		attr += attr[1];
+	}
+
+	result = rc_check_reply (recv_auth, BUFFER_LEN, secret, vector, data->seq_nbr);
+
+	length = ntohs(recv_auth->length)  - AUTH_HDR_LEN;
+	if (length > 0) {
+		data->receive_pairs = rc_avpair_gen(rh, NULL, recv_auth->data,
+		    length, 0);
+	} else {
+		data->receive_pairs = NULL;
+	}
+
+	close (sockfd);
+	memset (secret, '\0', sizeof (secret));
+
+	if (result != OK_RC) {
+		goto cleanup;
+	}
+
+	if (msg) {
+		*msg = '\0';
+		pos = 0;
+		vp = data->receive_pairs;
+		while (vp)
+		{
+			if ((vp = rc_avpair_get(vp, PW_REPLY_MESSAGE, 0)))
+			{
+				strappend(msg, PW_MAX_MSG_SIZE, &pos, vp->strvalue);
+				strappend(msg, PW_MAX_MSG_SIZE, &pos, "\n");
+				vp = vp->next;
+			}
+		}
+	}
+
+	if ((recv_auth->code == PW_ACCESS_ACCEPT) ||
+		(recv_auth->code == PW_PASSWORD_ACK) ||
+		(recv_auth->code == PW_ACCOUNTING_RESPONSE))
+	{
+		result = OK_RC;
+	}
+	else if ((recv_auth->code == PW_ACCESS_REJECT) ||
+		(recv_auth->code == PW_PASSWORD_REJECT))
+	{
+		result = REJECT_RC;
+	}
+	else
+	{
+		rc_log(LOG_ERR, "rc_send_server: received RADIUS server response neither ACCEPT nor REJECT, invalid");
+		result = BADRESP_RC;
+	}
+
+ cleanup:
+ 	if (auth_addr)
+ 		freeaddrinfo(auth_addr);
+
+	return result;
+#endif    
+}
+
+/** Verify items in returned packet
+ *
+ * @param auth a pointer to #AUTH_HDR.
+ * @param bufferlen the available buffer length.
+ * @param secret the secret used by the server.
+ * @param vector a random vector of %AUTH_VECTOR_LEN.
+ * @param seq_nbr a unique sequence number.
+ * @return %OK_RC upon success, %BADRESP_RC if anything looks funny.
+ */
+static int rc_check_reply (AUTH_HDR *auth, int bufferlen, char const *secret, unsigned char const *vector, uint8_t seq_nbr)
+{
+	int             secretlen;
+	int             totallen;
+	unsigned char   calc_digest[AUTH_VECTOR_LEN];
+	unsigned char   reply_digest[AUTH_VECTOR_LEN];
+#ifdef DIGEST_DEBUG
+	uint8_t		*ptr;
+#endif
+
+	totallen = ntohs (auth->length);
+	secretlen = (int)strlen (secret);
+
+	/* Do sanity checks on packet length */
+	if ((totallen < 20) || (totallen > 4096))
+	{
+		rc_log(LOG_ERR, "rc_check_reply: received RADIUS server response with invalid length");
+		return BADRESP_RC;
+	}
+
+	/* Verify buffer space, should never trigger with current buffer size and check above */
+	if ((totallen + secretlen) > bufferlen)
+	{
+		rc_log(LOG_ERR, "rc_check_reply: not enough buffer space to verify RADIUS server response");
+		return BADRESP_RC;
+	}
+
+	/* Verify that id (seq. number) matches what we sent */
+	if (auth->id != seq_nbr)
+	{
+		rc_log(LOG_ERR, "rc_check_reply: received non-matching id in RADIUS server response");
+		return BADRESP_RC;
+	}
+
+	/* Verify the reply digest */
+	memcpy ((char *) reply_digest, (char *) auth->vector, AUTH_VECTOR_LEN);
+	memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);
+	memcpy ((char *) auth + totallen, secret, secretlen);
+#ifdef DIGEST_DEBUG
+        rc_log(LOG_ERR, "Calculating digest on:");
+        for (ptr = (u_char *)auth; ptr < ((u_char *)auth) + totallen + secretlen; ptr += 32) {
+                char buf[65];
+                int i;
+
+                buf[0] = '\0';
+                for (i = 0; i < 32; i++) {
+                        if (ptr + i >= ((u_char *)auth) + totallen + secretlen)
+                                break;
+                        sprintf(buf + i * 2, "%.2X", ptr[i]);
+                }
+                rc_log(LOG_ERR, "  %s", buf);
+        }
+#endif
+	rc_md5_calc (calc_digest, (unsigned char *) auth, totallen + secretlen);
+#ifdef DIGEST_DEBUG
+	rc_log(LOG_ERR, "Calculated digest is:");
+        for (ptr = (u_char *)calc_digest; ptr < ((u_char *)calc_digest) + 16; ptr += 32) {
+                char buf[65];
+                int i;
+
+                buf[0] = '\0';
+                for (i = 0; i < 32; i++) {
+                        if (ptr + i >= ((u_char *)calc_digest) + 16)
+                                break;
+                        sprintf(buf + i * 2, "%.2X", ptr[i]);
+                }
+                rc_log(LOG_ERR, "  %s", buf);
+        }
+	rc_log(LOG_ERR, "Reply digest is:");
+        for (ptr = (u_char *)reply_digest; ptr < ((u_char *)reply_digest) + 16; ptr += 32) {
+                char buf[65];
+                int i;
+
+                buf[0] = '\0';
+                for (i = 0; i < 32; i++) {
+                        if (ptr + i >= ((u_char *)reply_digest) + 16)
+                                break;
+                        sprintf(buf + i * 2, "%.2X", ptr[i]);
+                }
+                rc_log(LOG_ERR, "  %s", buf);
+        }
+#endif
+
+	if (memcmp ((char *) reply_digest, (char *) calc_digest,
+		    AUTH_VECTOR_LEN) != 0)
+	{
+		rc_log(LOG_ERR, "rc_check_reply: received invalid reply digest from RADIUS server");
+		return BADRESP_RC;
+	}
+
+	return OK_RC;
+
+}
+
+/** Generates a random vector of AUTH_VECTOR_LEN octets
+ *
+ * @param vector a buffer with at least %AUTH_VECTOR_LEN bytes.
+ */
+static void rc_random_vector (unsigned char *vector)
+{
+	int             randno;
+	int             i;
+#if defined(HAVE_GETENTROPY)
+	if (getentropy(vector, AUTH_VECTOR_LEN) >= 0) {
+		return;
+	} /* else fall through */
+#elif defined(HAVE_DEV_URANDOM)
+	int		fd;
+
+/* well, I added this to increase the security for user passwords.
+   we use /dev/urandom here, as /dev/random might block and we don't
+   need that much randomness. BTW, great idea, Ted!     -lf, 03/18/95	*/
+
+	if ((fd = open(_PATH_DEV_URANDOM, O_RDONLY)) >= 0)
+	{
+		unsigned char *pos;
+		int readcount;
+
+		i = AUTH_VECTOR_LEN;
+		pos = vector;
+		while (i > 0)
+		{
+			readcount = read(fd, (char *)pos, i);
+			if (readcount >= 0) {
+				pos += readcount;
+				i -= readcount;
+			} else {
+				if (errno != EINTR && errno != EAGAIN)
+					goto fallback;
+			}
+		}
+
+		close(fd);
+		return;
+	} /* else fall through */
+#endif
+ fallback:
+	for (i = 0; i < AUTH_VECTOR_LEN;)
+	{
+		randno = random ();
+		memcpy ((char *) vector, (char *) &randno, sizeof (int));
+		vector += sizeof (int);
+		i += sizeof (int);
+	}
+
+	return;
+}

+ 389 - 0
thirdparty/FreeRadius/lib/util.c

@@ -0,0 +1,389 @@
+/*
+ * $Id: util.c,v 1.10 2010/02/04 10:31:41 aland Exp $
+ *
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ *
+ * Copyright (C) 1995,1996,1997 Lars Fenneberg
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ *
+ * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
+ * and Merit Network, Inc. All Rights Reserved
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+//#include <sys/time.h>
+
+#include <radius_config.h>
+#include <includes.h>
+#include <freeradius-client.h>
+#include "util.h"
+
+#define	RC_BUFSIZ	1024
+
+
+static char const * months[] =
+		{
+			"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+			"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+		};
+
+/** Turns printable string into correct tm struct entries
+ *
+ * @param valstr the printable date in 'day month year' format.
+ * @param tm the output struct.
+ */
+void rc_str2tm (char const *valstr, struct tm *tm)
+{
+	int             i;
+
+	/* Get the month */
+	for (i = 0; i < 12; i++)
+	{
+		if (strncmp (months[i], valstr, 3) == 0)
+		{
+			tm->tm_mon = i;
+			i = 13;
+		}
+	}
+
+	/* Get the Day */
+	tm->tm_mday = atoi (&valstr[4]);
+
+	/* Now the year */
+	tm->tm_year = atoi (&valstr[7]) - 1900;
+}
+
+/** Get the network interface name associated with this tty
+ *
+ * @param rh a handle to parsed configuration.
+ * @param tty the name of the tty.
+ * @return the network iface name.
+ */
+char *rc_getifname(rc_handle *rh, char const *tty)
+{
+#if defined(BSD4_4) || defined(linux)
+	int		fd;
+
+	if ((fd = open(tty, O_RDWR|O_NDELAY)) < 0) {
+		rc_log(LOG_ERR, "rc_getifname: can't open %s: %s", tty, strerror(errno));
+		return NULL;
+	}
+#endif
+
+#ifdef BSD4_4
+	strcpy(rh->ifname,ttyname(fd));
+	if (strlen(rh->ifname) < 1) {
+		rc_log(LOG_ERR, "rc_getifname: can't get attached interface of %s: %s", tty, strerror(errno));
+		close(fd);
+		return NULL;
+	}
+#elif linux
+	if (ioctl(fd, SIOCGIFNAME, rh->ifname) < 0) {
+		rc_log(LOG_ERR, "rc_getifname: can't ioctl %s: %s", tty, strerror(errno));
+		close(fd);
+		return NULL;
+	}
+#else
+	return NULL;
+#endif
+
+#if defined(BSD4_4) || defined(linux)
+	close(fd);
+	return rh->ifname;
+#endif
+}
+
+/** Reads in a string from the user (with or witout echo)
+ *
+ * @param rh a handle to parsed configuration.
+ * @param prompt the prompt to print.
+ * @param do_echo whether to echo characters.
+ * @return the data user typed or NULL.
+ */
+#ifndef _MSC_VER
+char *rc_getstr (rc_handle *rh, char const *prompt, int do_echo)
+{
+#if 0  
+	int             in, out;
+	char           *p;
+	struct termios  term_old, term_new;
+	int		is_term, flags, old_flags;
+	char		c;
+	int		flushed = 0;
+	sigset_t        newset;
+	sigset_t        oldset;
+
+	in = fileno(stdin);
+	out = fileno(stdout);
+
+	(void) sigemptyset (&newset);
+	(void) sigaddset (&newset, SIGINT);
+	(void) sigaddset (&newset, SIGTSTP);
+	(void) sigaddset (&newset, SIGQUIT);
+
+	(void) sigprocmask (SIG_BLOCK, &newset, &oldset);
+
+	if ((is_term = isatty(in)))
+	{
+
+		(void) tcgetattr (in, &term_old);
+		term_new = term_old;
+		if (do_echo)
+			term_new.c_lflag |= ECHO;
+		else
+			term_new.c_lflag &= ~ECHO;
+
+		if (tcsetattr (in, TCSAFLUSH, &term_new) == 0)
+			flushed = 1;
+
+	}
+	else
+	{
+		is_term = 0;
+		if ((flags = fcntl(in, F_GETFL, 0)) >= 0) {
+			old_flags = flags;
+			flags |= O_NONBLOCK;
+
+			fcntl(in, F_SETFL, flags);
+
+			while (read(in, &c, 1) > 0)
+				/* nothing */;
+
+			fcntl(in, F_SETFL, old_flags);
+
+			flushed = 1;
+		}
+	}
+
+	(void)write(out, prompt, strlen(prompt));
+
+	/* well, this looks ugly, but it handles the following end of line
+	   markers: \r \r\0 \r\n \n \n\r, at least at a second pass */
+
+	p = rh->buf;
+	for (;;)
+	{
+		if (read(in, &c, 1) <= 0)
+			return NULL;
+
+		if (!flushed && ((c == '\0') || (c == '\r') || (c == '\n'))) {
+			flushed = 1;
+			continue;
+		}
+
+		if ((c == '\r') || (c == '\n'))
+			break;
+
+		flushed = 1;
+
+		if (p < rh->buf + GETSTR_LENGTH)
+		{
+			if (do_echo && !is_term)
+				(void)write(out, &c, 1);
+			*p++ = c;
+		}
+	}
+
+	*p = '\0';
+
+	if (!do_echo || !is_term) (void)write(out, "\r\n", 2);
+
+	if (is_term)
+		tcsetattr (in, TCSAFLUSH, &term_old);
+	else {
+		if ((flags = fcntl(in, F_GETFL, 0)) >= 0) {
+			old_flags = flags;
+			flags |= O_NONBLOCK;
+
+			fcntl(in, F_SETFL, flags);
+
+			while (read(in, &c, 1) > 0)
+				/* nothing */;
+
+			fcntl(in, F_SETFL, old_flags);
+		}
+	}
+
+	(void) sigprocmask (SIG_SETMASK, &oldset, NULL);
+#endif
+	return rh->buf;
+}
+#endif
+
+void rc_mdelay(int msecs)
+{
+#if 0  
+	struct timeval tv;
+
+	tv.tv_sec = (int) msecs / 1000;
+	tv.tv_usec = (msecs % 1000) * 1000;
+
+	select(0, NULL, NULL, NULL, &tv);
+#endif    
+}
+
+/** Generate a quite unique string
+ *
+ * @note not that unique at all...
+ *
+ * @param rh a handle to parsed configuration.
+ * @return unique string. Memory does not need to be freed.
+ */
+
+char *rc_mksid (rc_handle *rh)
+{
+  //snprintf (rh->buf1, sizeof(rh->buf1), "%08lX%04X", (unsigned long int) time (NULL), (unsigned int) getpid ());
+  return rh->buf1;
+}
+
+/** Initialises new Radius Client handle
+ *
+ * @return a new rc_handle (free with rc_destroy).
+ */
+rc_handle *rc_new(void)
+{
+	rc_handle *rh;
+
+	rh = malloc(sizeof(*rh));
+	if (rh == NULL) {
+                rc_log(LOG_CRIT, "rc_new: out of memory");
+                return NULL;
+        }
+	memset(rh, 0, sizeof(*rh));
+	return rh;
+}
+
+/** Destroys Radius Client handle reclaiming all memory
+ *
+ * @param rh The Radius client handle to free.
+ */
+void rc_destroy(rc_handle *rh)
+{
+	rc_map2id_free(rh);
+	rc_dict_free(rh);
+	rc_config_free(rh);
+	free(rh);
+}
+
+/** Get next line from the stream.
+ *
+ * @param fp a %FILE pointer.
+ * @param len output length.
+ * @return the next line in an allocated buffer.
+ */
+char *rc_fgetln(FILE *fp, size_t *len)
+{
+	static char *buf = NULL;
+	static size_t bufsiz = 0;
+	char *ptr;
+
+	if (buf == NULL) {
+		bufsiz = RC_BUFSIZ;
+		if ((buf = malloc(bufsiz)) == NULL)
+			return NULL;
+	}
+
+	if (fgets(buf, (int)bufsiz, fp) == NULL)
+		return NULL;
+	*len = 0;
+
+	while ((ptr = strchr(&buf[*len], '\n')) == NULL) {
+		size_t nbufsiz = bufsiz + RC_BUFSIZ;
+		char *nbuf = realloc(buf, nbufsiz);
+
+		if (nbuf == NULL) {
+			int oerrno = errno;
+			free(buf);
+			errno = oerrno;
+			buf = NULL;
+			return NULL;
+		} else
+			buf = nbuf;
+
+		*len = bufsiz;
+		if (fgets(&buf[bufsiz], RC_BUFSIZ, fp) == NULL)
+			return buf;
+
+		bufsiz = nbufsiz;
+	}
+
+	*len = (ptr - buf) + 1;
+	return buf;
+}
+
+/** Returns the current time as a double.
+ *
+ * @return current time (seconds since epoch) expressed as
+ * 	double-precision floating point number.
+ */
+double rc_getctime(void)
+{
+#if 0  
+    struct timeval timev;
+
+    if (gettimeofday(&timev, NULL) == -1)
+        return -1;
+
+    return timev.tv_sec + ((double)timev.tv_usec) / 1000000.0;
+#endif    
+    return RTC_GetUnixTime();
+}
+
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Copyright 2006  The FreeRADIUS server project
+ */
+
+#ifndef HAVE_STRLCPY
+
+/*
+ * Copy src to string dst of size siz.  At most siz-1 characters
+ * will be copied.  Always NUL terminates (unless siz == 0).
+ * Returns strlen(src); if retval >= siz, truncation occurred.
+ */
+size_t
+rc_strlcpy(char *dst, char const *src, size_t siz)
+{
+    char *d = dst;
+    char const *s = src;
+    size_t n = siz;
+
+    /* Copy as many bytes as will fit */
+    if (n != 0 && --n != 0) {
+        do {
+            if ((*d++ = *s++) == 0)
+                break;
+        } while (--n != 0);
+    }
+
+    /* Not enough room in dst, add NUL and traverse rest of src */
+    if (n == 0) {
+        if (siz != 0)
+            *d = '\0';      /* NUL-terminate dst */
+        while (*s++)
+            ;
+    }
+
+    return(s - src - 1);    /* count does not include NUL */
+}
+
+#endif
+

+ 50 - 0
thirdparty/FreeRadius/lib/util.h

@@ -0,0 +1,50 @@
+/*
+ * util.h        Utility structures and prototypes.
+ *
+ * License:	BSD
+ *
+ */
+
+#ifndef UTIL_H
+# define UTIL_H
+
+#include <string.h>
+
+#ifndef HAVE_STRLCPY
+size_t rc_strlcpy(char *dst, char const *src, size_t siz);
+# define strlcpy rc_strlcpy
+#endif
+
+#include <includes.h>
+
+#if !defined(SA_LEN)
+#define SA_LEN(sa) \
+  (((sa)->sa_family == AF_INET) ? \
+    sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6))
+
+#define SS_LEN(sa) \
+  (((sa)->ss_family == AF_INET) ? \
+    sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6))
+#endif
+
+#define SA_GET_INADDR(sa) \
+  (((sa)->sa_family == AF_INET) ? \
+    ((void*)&(((struct sockaddr_in*)(sa))->sin_addr)) : ((void*)&(((struct sockaddr_in6*)(sa))->sin6_addr)))
+
+#define SA_GET_INLEN(sa) \
+  ((sa)->sa_family == AF_INET) ? \
+    sizeof(struct in_addr) : sizeof(struct in6_addr)
+
+//int rc_find_server_addr(rc_handle const *, char const *, struct addrinfo **, char *, unsigned flags);
+int rc_find_server_addr(rc_handle const *rh, char const *server_name, struct addrinfo** info, char *secret, unsigned flags);
+
+/* flags to rc_getaddrinfo() */
+#define PW_AI_PASSIVE		1
+#define PW_AI_AUTH		(1<<1)
+#define PW_AI_ACCT		(1<<2)
+
+struct addrinfo *rc_getaddrinfo (char const *host, unsigned flags);
+void rc_own_bind_addr(rc_handle *rh, struct sockaddr_storage *lia);
+
+#endif /* UTIL_H */
+

+ 103 - 0
thirdparty/FreeRadius/radius_config.h

@@ -0,0 +1,103 @@
+/******************************* (C) LiteMesh **********************************
+ * @module  template
+ * @file    template.h
+ * @version 1.0.0
+ * @date    XX.XX.XXXX
+ * $brief   template
+ *******************************************************************************
+ * @history     Version  Author         Comment
+ * XX.XX.XXXX   1.0.0    Telenkov D.A.  First release.
+ *******************************************************************************
+ */
+
+/* Define to prevent recursive  ----------------------------------------------*/
+#ifndef __RADIUS_CONFIG_H
+#define __RADIUS_CONFIG_H
+
+#include <stdint.h>
+#include <string.h>
+
+#define RC_LOG
+#define STDC_HEADERS
+#define HAVE_RAND       //  Рандом генератор
+//#define HAVE_GETENTROPY // ?
+
+// some unix defines
+#define LOG_CRIT    0
+#define LOG_ERR     0
+#define LOG_WARNING 0
+
+//typedef unsigned int size_t;
+
+// some unix structs
+
+/*
+ * Desired design of maximum size and alignment (see RFC2553)
+ */
+#define _K_SS_MAXSIZE	128	/* Implementation specific max size */
+#define _K_SS_ALIGNSIZE	(__alignof__ (struct sockaddr *))
+				/* Implementation specific desired alignment */
+
+typedef unsigned short __kernel_sa_family_t;
+
+struct __kernel_sockaddr_storage {
+	__kernel_sa_family_t	ss_family;		/* address family */
+	/* Following field(s) are implementation specific */
+	char		data[_K_SS_MAXSIZE - sizeof(unsigned short)];
+				/* space to achieve desired size, */
+				/* _SS_MAXSIZE value minus size of ss_family */
+} ;	/* force desired alignment */
+
+// -----------------------------------------------------------------------------
+
+typedef __kernel_sa_family_t	sa_family_t;
+
+// -----------------------------------------------------------------------------
+/*
+struct sockaddr {
+	char	sa_len;			// total length 
+	char	sa_family;		// address family 
+	char	sa_data[14];	// actually longer; address value 
+};
+*/
+
+#define _SS_MAXSIZE    128  /* Implementation specific max size */
+#define _SS_ALIGNSIZE  (sizeof (int64_t))
+
+#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(sa_family_t))
+#define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof(sa_family_t)+ \
+                      _SS_PAD1SIZE + _SS_ALIGNSIZE))
+struct sockaddr_storage {
+    sa_family_t  ss_family;  /* Address family. */
+/*
+ *  Following fields are implementation-defined.
+ */
+    char _ss_pad1[_SS_PAD1SIZE];
+        /* 6-byte pad; this is to make implementation-defined
+           pad up to alignment field that follows explicit in
+           the data structure. */
+    int64_t _ss_align;  /* Field to force desired structure
+                           storage alignment. */
+    char _ss_pad2[_SS_PAD2SIZE];
+        /* 112-byte pad to achieve desired size,
+           _SS_MAXSIZE value minus size of ss_family
+           __ss_pad1, __ss_align fields is 112. */
+};
+
+
+struct addrinfo {
+    int              ai_flags;     // AI_PASSIVE, AI_CANONNAME, etc.
+    int              ai_family;    // AF_INET, AF_INET6, AF_UNSPEC
+    int              ai_socktype;  // SOCK_STREAM, SOCK_DGRAM
+    int              ai_protocol;  // use 0 for "any"
+    size_t           ai_addrlen;   // size of ai_addr in bytes
+    struct sockaddr *ai_addr;      // struct sockaddr_in or _in6
+    char            *ai_canonname; // full canonical hostname
+
+    struct addrinfo *ai_next;      // linked list, next node
+};
+
+
+#endif /* #ifndef __RADIUS_CONFIG_H */
+
+/****************************** (C) LiteMesh ***************** end of file ****/

+ 212 - 0
thirdparty/FreeRadius/radius_user.c

@@ -0,0 +1,212 @@
+/********************************* (C) РОТЕК ***********************************
+ * @module  template
+ * @file    template.c
+ * @version 1.0.0
+ * @date    XX.XX.XXXX
+ * $brief   template
+ *******************************************************************************
+ * @history     Version  Author         Comment
+ * XX.XX.XXXX   1.0.0    Telenkov D.A.  First release.
+ *******************************************************************************
+ */
+
+#include "stm32f4xx.h"  
+#include "radius_user.h"
+
+#include "FreeRTOS.h"
+#include "task.h"
+
+#include "freeradius-client.h"
+#include "options.h"
+
+rc_handle	rcHandle;
+
+int auth_order = AUTH_LOCAL_SND;
+int login_tries = 4;
+int login_timeout = 60;
+char* nologin = "?";
+char* issue = "?";
+char* authserver = "192.168.1.2:1645";
+char* acctserver = "0";
+char* servers = "?";
+char* dictionary = "?";
+char *login_radius = "?";
+char *mapfile = "?";
+char *default_realm = NULL;
+int radius_timeout = 10;
+int radius_retries = 3;
+int radius_deadtime = 0;
+char *bindaddr = "*";
+char *login_local = "?";
+
+OPTION      rcOptions[] = {
+{"auth_order",	 	OT_AUO, ST_UNDEF, (void*)&auth_order}, // AUTH_LOCAL_FST AUTH_RADIUS_FST AUTH_LOCAL_SND AUTH_RADIUS_SND
+{"login_tries",	 	OT_INT, ST_UNDEF, (void*)&login_tries},
+{"login_timeout",	OT_INT, ST_UNDEF, (void*)&login_timeout},
+{"nologin",		    OT_STR, ST_UNDEF, NULL},
+{"issue",		    OT_STR, ST_UNDEF, NULL},
+// RADIUS specific options 
+{"authserver",		OT_SRV, ST_UNDEF, (void*)&authserver},
+{"acctserver",		OT_SRV, ST_UNDEF, (void*)&acctserver},
+{"servers",		    OT_STR, ST_UNDEF, (void*)&servers},
+{"dictionary",		OT_STR, ST_UNDEF, (void*)&dictionary},
+{"login_radius",	OT_STR, ST_UNDEF, (void*)&login_radius},
+{"mapfile",		    OT_STR, ST_UNDEF, (void*)&mapfile},
+{"default_realm",	OT_STR, ST_UNDEF, (void*)&default_realm},
+{"radius_timeout",	OT_INT, ST_UNDEF, (void*)&radius_timeout},
+{"radius_retries",	OT_INT,	ST_UNDEF, (void*)&radius_retries},
+{"radius_deadtime",	OT_INT, ST_UNDEF, (void*)&radius_deadtime},
+{"bindaddr",		OT_STR, ST_UNDEF, (void*)&bindaddr},
+// local options 
+{"login_local",		OT_STR, ST_UNDEF, (void*)&login_local},
+};
+
+DICT_ATTR   attr_1;
+DICT_ATTR   attr_2;
+DICT_ATTR   attr_3;
+
+
+/**
+  * @brief  
+  */
+int RD_TestInit(void)
+{
+    int         result;
+	char		username[128];
+	char        passwd[AUTH_PASS_LEN + 1];
+	VALUE_PAIR 	*send, *received;
+	uint32_t	service;
+	char 		msg[PW_MAX_MSG_SIZE], username_realm[256];
+	char		*default_realm;
+	  
+    // Моя подготовка 
+    memset(username, 0, 128);
+    memset(passwd, 0, AUTH_PASS_LEN + 1);
+    memset(msg, 0, PW_MAX_MSG_SIZE);
+    memset(username_realm, 0, 256);
+    
+    
+    // Просто копируем структуру настроек которая жесто задана
+    rc_read_config(&rcHandle);
+   
+    // Словарь пока опускаем и не инициализируем
+    //if (rc_read_dictionary(&rcHandle, rc_conf_str(&rcHandle, "dictionary")) != 0)
+	//	return ERROR_RC;
+  
+    // Заполняем словарь
+    // 1. User name
+    strcpy(attr_1.name, "test1");
+    attr_1.value = 1;
+    attr_1.type = PW_TYPE_STRING;
+    attr_1.next = NULL;
+    
+    // 2. Password
+    strcpy(attr_2.name, "12345");
+    attr_2.value = 2;
+    attr_2.type = PW_TYPE_STRING;
+    attr_2.next = &attr_1;
+    
+    // 2. Service type
+    //strcpy(attr_3.name, "Service-Type");
+    //attr_3.value = 6;
+    //attr_3.type = PW_TYPE_INTEGER;
+    //attr_3.next = &attr_2;
+    //strcpy(attr_3.name, "ervice-Type");
+    attr_3.value = 244;
+    attr_3.type = PW_TYPE_STRING;
+    attr_3.next = &attr_2;
+    
+    rcHandle.dictionary_attributes = &attr_3;
+    
+    // Не понял что за параметра, пока NULL
+    //default_realm = rc_conf_str(rh, "default_realm");
+    default_realm = NULL;
+
+    // Рараметры ожидаются от пользователя
+    //strncpy(username, "dtelenkov", 9);
+    strncpy(username, "test1", 5);
+    strncpy(passwd, "12345", 5);
+    //strncpy(username, rc_getstr (rh, "login: ",1), sizeof(username));
+	//strncpy (passwd, rc_getstr(rh, "Password: ",0), sizeof (passwd));
+    
+    send = NULL;
+        
+    /*
+	 * Fill in User-Name
+	 */
+
+	strncpy(username_realm, username, sizeof(username_realm));
+
+	/* Append default realm */
+    /*
+	if ((strchr(username_realm, '@') == NULL) && default_realm &&
+	    (*default_realm != '\0'))
+	{
+		strncat(username_realm, "@", sizeof(username_realm)-strlen(username_realm)-1);
+		strncat(username_realm, default_realm, sizeof(username_realm)-strlen(username_realm)-1);
+	}
+    */
+    
+	if (rc_avpair_add(&rcHandle, &send, PW_USER_NAME, username_realm, -1, 0) == NULL)
+		return ERROR_RC;
+    
+	/*
+	 * Fill in User-Password
+	 */
+	if (rc_avpair_add(&rcHandle, &send, PW_USER_PASSWORD, passwd, -1, 0) == NULL)
+		return ERROR_RC;
+
+	/*
+	 * Fill in Service-Type
+	 */
+	service = PW_AUTHENTICATE_ONLY;
+	if (rc_avpair_add(&rcHandle, &send, PW_SERVICE_TYPE, &service, -1, 0) == NULL)
+		return ERROR_RC;
+#if 1
+	result = rc_auth(&rcHandle, 0, send, &received, msg);
+
+	if (result == OK_RC)
+	{
+		fprintf(stderr, "\"%s\" RADIUS Authentication OK\n", username);
+	}
+	else
+	{
+		fprintf(stderr, "\"%s\" RADIUS Authentication failure (RC=%i)\n", username, result);
+	}
+
+	
+#endif
+	send = NULL;
+    
+    return 0;
+}
+
+void initFdsets(fdsets *sets)
+{
+    memset((sets)->buf1, 0xab, 8); 
+    memset((sets)->buf2, 0xab, 8); 
+    memset((sets)->buf3, 0xab, 8); 
+    memset((sets)->buf4, 0xab, 8); 
+}
+
+bool recvSelect(fdsets *sets, int *socket, uint32_t timeout)
+{
+    struct timeval tv;
+
+    tv.tv_sec = 0;
+    tv.tv_usec = timeout * 1000;
+      
+    FD_ZERO(&(sets->readset));
+    FD_SET(*socket, &sets->readset);
+    FD_ZERO(&sets->errset);
+    FD_SET(*socket, &sets->errset);
+        
+    lwip_select(*socket + 1, &sets->readset, NULL, &sets->errset, &tv);
+        
+    if (FD_ISSET(*socket, &sets->readset)) 
+        return true;
+
+    return false;
+}
+
+/********************************* (C) РОТЕК **********************************/

+ 44 - 0
thirdparty/FreeRadius/radius_user.h

@@ -0,0 +1,44 @@
+/******************************* (C) LiteMesh **********************************
+ * @module  template
+ * @file    template.h
+ * @version 1.0.0
+ * @date    XX.XX.XXXX
+ * $brief   template
+ *******************************************************************************
+ * @history     Version  Author         Comment
+ * XX.XX.XXXX   1.0.0    Telenkov D.A.  First release.
+ *******************************************************************************
+ */
+
+/* Define to prevent recursive  ----------------------------------------------*/
+#ifndef __RADIUS_USER_H
+#define __RADIUS_USER_H
+
+#include "lwip/sockets.h"
+#include <stdbool.h>
+
+
+typedef struct 
+{
+    u8_t   buf1[8];
+    fd_set readset;
+    u8_t   buf2[8];
+    fd_set writeset;
+    u8_t   buf3[8];
+    fd_set errset;
+    u8_t   buf4[8];
+  
+} fdsets;
+
+/**
+  * @brief  
+  */
+int RD_TestInit(void);
+
+void initFdsets(fdsets *sets);
+
+bool recvSelect(fdsets *sets, int *socket, uint32_t timeout);
+
+#endif /* #ifndef __RADIUS_USER_H */
+
+/****************************** (C) LiteMesh ***************** end of file ****/

+ 28 - 0
thirdparty/FreeRadius/src/Makefile.am

@@ -0,0 +1,28 @@
+#
+# $Id: Makefile.am,v 1.7 2007/03/01 17:50:38 cparker Exp $
+#
+# Copyright (C) 1995,1997,1998 Lars Fenneberg
+#
+# See the file COPYRIGHT for the respective terms and conditions. 
+#
+
+AUTOMAKE_OPTIONS = foreign
+
+pkgsysconfdir=@pkgsysconfdir@
+
+DEFS = @DEFS@ -DRC_CONFIG_FILE=\"${pkgsysconfdir}/radiusclient.conf\" \
+	      -DRC_SECURE_PATH=\"@RC_SECURE_PATH@\"
+INCLUDES = -I$(srcdir) -I$(top_srcdir)/include -I$(top_builddir)
+LDADD = ../lib/libfreeradius-client.la
+
+CLEANFILES = *~
+
+noinst_HEADERS = radlogin.h
+
+sbin_PROGRAMS = radlogin radstatus radacct radexample radiusclient radembedded
+radlogin_SOURCES = radlogin.c radius.c local.c
+radacct_SOURCES = radacct.c
+radstatus_SOURCES = radstatus.c
+radexample_SOURCES = radexample.c
+radiusclient_SOURCES = radiusclient.c
+radembedded_SOURCES = radembedded.c

+ 706 - 0
thirdparty/FreeRadius/src/Makefile.in

@@ -0,0 +1,706 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# $Id: Makefile.am,v 1.7 2007/03/01 17:50:38 cparker Exp $
+#
+# Copyright (C) 1995,1997,1998 Lars Fenneberg
+#
+# See the file COPYRIGHT for the respective terms and conditions. 
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+sbin_PROGRAMS = radlogin$(EXEEXT) radstatus$(EXEEXT) radacct$(EXEEXT) \
+	radexample$(EXEEXT) radiusclient$(EXEEXT) radembedded$(EXEEXT)
+subdir = src
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp \
+	$(noinst_HEADERS)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(sbindir)"
+PROGRAMS = $(sbin_PROGRAMS)
+am_radacct_OBJECTS = radacct.$(OBJEXT)
+radacct_OBJECTS = $(am_radacct_OBJECTS)
+radacct_LDADD = $(LDADD)
+radacct_DEPENDENCIES = ../lib/libfreeradius-client.la
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+am_radembedded_OBJECTS = radembedded.$(OBJEXT)
+radembedded_OBJECTS = $(am_radembedded_OBJECTS)
+radembedded_LDADD = $(LDADD)
+radembedded_DEPENDENCIES = ../lib/libfreeradius-client.la
+am_radexample_OBJECTS = radexample.$(OBJEXT)
+radexample_OBJECTS = $(am_radexample_OBJECTS)
+radexample_LDADD = $(LDADD)
+radexample_DEPENDENCIES = ../lib/libfreeradius-client.la
+am_radiusclient_OBJECTS = radiusclient.$(OBJEXT)
+radiusclient_OBJECTS = $(am_radiusclient_OBJECTS)
+radiusclient_LDADD = $(LDADD)
+radiusclient_DEPENDENCIES = ../lib/libfreeradius-client.la
+am_radlogin_OBJECTS = radlogin.$(OBJEXT) radius.$(OBJEXT) \
+	local.$(OBJEXT)
+radlogin_OBJECTS = $(am_radlogin_OBJECTS)
+radlogin_LDADD = $(LDADD)
+radlogin_DEPENDENCIES = ../lib/libfreeradius-client.la
+am_radstatus_OBJECTS = radstatus.$(OBJEXT)
+radstatus_OBJECTS = $(am_radstatus_OBJECTS)
+radstatus_LDADD = $(LDADD)
+radstatus_DEPENDENCIES = ../lib/libfreeradius-client.la
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+SOURCES = $(radacct_SOURCES) $(radembedded_SOURCES) \
+	$(radexample_SOURCES) $(radiusclient_SOURCES) \
+	$(radlogin_SOURCES) $(radstatus_SOURCES)
+DIST_SOURCES = $(radacct_SOURCES) $(radembedded_SOURCES) \
+	$(radexample_SOURCES) $(radiusclient_SOURCES) \
+	$(radlogin_SOURCES) $(radstatus_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_CFLAGS = @CRYPTO_CFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@ -DRC_CONFIG_FILE=\"${pkgsysconfdir}/radiusclient.conf\" \
+	      -DRC_SECURE_PATH=\"@RC_SECURE_PATH@\"
+
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBVERSION = @LIBVERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NETTLE_CFLAGS = @NETTLE_CFLAGS@
+NETTLE_LIBS = @NETTLE_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+RC_LOG_FACILITY = @RC_LOG_FACILITY@
+RC_SECURE_PATH = @RC_SECURE_PATH@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgsysconfdir = @pkgsysconfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = foreign
+INCLUDES = -I$(srcdir) -I$(top_srcdir)/include -I$(top_builddir)
+LDADD = ../lib/libfreeradius-client.la
+CLEANFILES = *~
+noinst_HEADERS = radlogin.h
+radlogin_SOURCES = radlogin.c radius.c local.c
+radacct_SOURCES = radacct.c
+radstatus_SOURCES = radstatus.c
+radexample_SOURCES = radexample.c
+radiusclient_SOURCES = radiusclient.c
+radembedded_SOURCES = radembedded.c
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+	@$(NORMAL_INSTALL)
+	@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \
+	fi; \
+	for p in $$list; do echo "$$p $$p"; done | \
+	sed 's/$(EXEEXT)$$//' | \
+	while read p p1; do if test -f $$p \
+	 || test -f $$p1 \
+	  ; then echo "$$p"; echo "$$p"; else :; fi; \
+	done | \
+	sed -e 'p;s,.*/,,;n;h' \
+	    -e 's|.*|.|' \
+	    -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+	sed 'N;N;N;s,\n, ,g' | \
+	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+	    if ($$2 == $$4) files[d] = files[d] " " $$1; \
+	    else { print "f", $$3 "/" $$4, $$1; } } \
+	  END { for (d in files) print "f", d, files[d] }' | \
+	while read type dir files; do \
+	    if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+	    test -z "$$files" || { \
+	    echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
+	    $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
+	    } \
+	; done
+
+uninstall-sbinPROGRAMS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	  sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+	      -e 's/$$/$(EXEEXT)/' \
+	`; \
+	test -n "$$list" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(sbindir)" && rm -f $$files
+
+clean-sbinPROGRAMS:
+	@list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+
+radacct$(EXEEXT): $(radacct_OBJECTS) $(radacct_DEPENDENCIES) $(EXTRA_radacct_DEPENDENCIES) 
+	@rm -f radacct$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(radacct_OBJECTS) $(radacct_LDADD) $(LIBS)
+
+radembedded$(EXEEXT): $(radembedded_OBJECTS) $(radembedded_DEPENDENCIES) $(EXTRA_radembedded_DEPENDENCIES) 
+	@rm -f radembedded$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(radembedded_OBJECTS) $(radembedded_LDADD) $(LIBS)
+
+radexample$(EXEEXT): $(radexample_OBJECTS) $(radexample_DEPENDENCIES) $(EXTRA_radexample_DEPENDENCIES) 
+	@rm -f radexample$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(radexample_OBJECTS) $(radexample_LDADD) $(LIBS)
+
+radiusclient$(EXEEXT): $(radiusclient_OBJECTS) $(radiusclient_DEPENDENCIES) $(EXTRA_radiusclient_DEPENDENCIES) 
+	@rm -f radiusclient$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(radiusclient_OBJECTS) $(radiusclient_LDADD) $(LIBS)
+
+radlogin$(EXEEXT): $(radlogin_OBJECTS) $(radlogin_DEPENDENCIES) $(EXTRA_radlogin_DEPENDENCIES) 
+	@rm -f radlogin$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(radlogin_OBJECTS) $(radlogin_LDADD) $(LIBS)
+
+radstatus$(EXEEXT): $(radstatus_OBJECTS) $(radstatus_DEPENDENCIES) $(EXTRA_radstatus_DEPENDENCIES) 
+	@rm -f radstatus$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(radstatus_OBJECTS) $(radstatus_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/local.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radacct.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radembedded.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radexample.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radius.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radiusclient.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radlogin.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radstatus.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(sbindir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \
+	mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-sbinPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-sbinPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-sbinPROGRAMS cscopelist-am ctags ctags-am \
+	distclean distclean-compile distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-sbinPROGRAMS install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-am uninstall uninstall-am uninstall-sbinPROGRAMS
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:

+ 84 - 0
thirdparty/FreeRadius/src/local.c

@@ -0,0 +1,84 @@
+/*
+ * $Id: local.c,v 1.5 2007/01/06 20:15:35 pnixon Exp $
+ *
+ * Copyright (C) 1996 Lars Fenneberg
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+#include <config.h>
+#include <includes.h>
+#include <freeradius-client.h>
+#include <messages.h>
+#include <radlogin.h>
+
+extern ENV *env;
+
+LFUNC auth_local(char const *username, char const *passwd)
+{
+	struct passwd	*pw;
+	char		*xpasswd;
+#ifdef SHADOW_PASSWORD
+	struct spwd	*spw;
+#endif
+
+	if ((pw = getpwnam(username)) == NULL) {
+		endpwent();
+		rc_log(LOG_NOTICE, "authentication FAILED, type local, username %s", username);
+		printf(SC_LOCAL_FAILED);
+		return NULL;
+	}
+	endpwent();
+
+#ifdef SHADOW_PASSWORD
+        if((spw = getspnam(pw->pw_name)) == NULL) {
+			endspent();
+			rc_log(LOG_NOTICE, "authentication FAILED, type local, username %s", username);
+			printf(SC_LOCAL_FAILED);
+			return NULL;
+        }
+        else
+        {
+        	pw->pw_passwd = spw->sp_pwdp;
+        }
+        endspent();
+#endif /* SHADOW_PASSWORD */
+
+	xpasswd = crypt(passwd, pw->pw_passwd);
+
+	if (*pw->pw_passwd == '\0' || !xpasswd || strcmp(xpasswd, pw->pw_passwd)) {
+		rc_log(LOG_NOTICE, "authentication FAILED, type local, username %s", username);
+		printf(SC_LOCAL_FAILED);
+		return NULL;
+	}
+
+	rc_log(LOG_NOTICE, "authentication OK, type local, username %s", username);
+	printf(SC_LOCAL_OK);
+
+	return local_login;
+}
+
+void
+local_login(rc_handle *rh, char const *username)
+{
+	char *login_local = rc_conf_str(rh, "login_local");
+
+	/* login should spot this... but who knows what old /bin/logins
+	 * may be still around
+	 */
+	if (*username == '-') {
+		rc_log(LOG_WARNING, "username can't start with a dash");
+		exit(ERROR_RC);
+	}
+	/* the new shadow login seems to require either a -r or a -h
+	 * flag for -f to work (so source code, lmain.c) so we supply
+	 * it here. shouldn't hurt on other systems,	-lf, 03/13/96
+	 */
+	execle(login_local, login_local, "-h", "localhost", "-f", username, NULL, env->env);
+	rc_log(LOG_ERR, "couldn't execute %s: %s", login_local, strerror(errno));
+	sleep(1);	/* give the user time to read */
+	exit(ERROR_RC);
+}

+ 150 - 0
thirdparty/FreeRadius/src/radacct.c

@@ -0,0 +1,150 @@
+/*
+ * $Id: radacct.c,v 1.6 2007/07/11 17:29:30 cparker Exp $
+ *
+ * Copyright (C) 1995,1996 Lars Fenneberg
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+static char	rcsid[] =
+		"$Id: radacct.c,v 1.6 2007/07/11 17:29:30 cparker Exp $";
+
+#include <config.h>
+#include <includes.h>
+#include <freeradius-client.h>
+#include <messages.h>
+#include <pathnames.h>
+
+static char *pname;
+
+void usage(void)
+{
+	fprintf(stderr,"Usage: %s [-Vh] [-f <config_file>] [-i <client_port>]\n\n", pname);
+	fprintf(stderr,"  -V            output version information\n");
+	fprintf(stderr,"  -h            output this text\n");
+	fprintf(stderr,"  -f		filename of alternate config file\n");
+	fprintf(stderr,"  -i            ttyname to send to the server\n");
+	exit(ERROR_RC);
+}
+
+void version(void)
+{
+	fprintf(stderr,"%s: %s\n", pname ,rcsid);
+	exit(ERROR_RC);
+}
+
+int
+main (int argc, char **argv)
+{
+	int			result = ERROR_RC;
+	VALUE_PAIR	*send = NULL;
+   	uint32_t		client_port;
+   	int			c;
+	VALUE_PAIR	*vp;
+	DICT_VALUE  *dval;
+	char *username, *service, *fproto, *type;
+	char *path_radiusclient_conf = RC_CONFIG_FILE;
+	char *ttyn = NULL;
+	rc_handle *rh;
+
+	extern char *optarg;
+
+	pname = (pname = strrchr(argv[0],'/'))?pname+1:argv[0];
+
+	rc_openlog(pname);
+
+	while ((c = getopt(argc,argv,"f:i:hV")) > 0)
+	{
+		switch(c)
+		{
+			case 'f':
+				path_radiusclient_conf = optarg;
+				break;
+			case 'i':
+				ttyn = optarg;
+				break;
+			case 'V':
+				version();
+				break;
+			case 'h':
+				usage();
+				break;
+			default:
+				exit(ERROR_RC);
+				break;
+		}
+	}
+
+	if ((rh = rc_read_config(path_radiusclient_conf)) == NULL)
+		exit(ERROR_RC);
+
+	if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0)
+		exit (ERROR_RC);
+
+	if (rc_read_mapfile(rh, rc_conf_str(rh, "mapfile")) != 0)
+		exit (ERROR_RC);
+
+	if (ttyn != NULL)
+	{
+		client_port = rc_map2id(rh, ttyn);
+	}
+	else
+	{
+		/* we take stdout here, because stdin is usually connected
+	 	 *  to our input file
+	 	 */
+	 	if ((ttyn = ttyname(1)) != NULL)
+	 	{
+			client_port = rc_map2id(rh, ttyn);
+		}
+		else
+		{
+			client_port = 0;
+		}
+	}
+
+	if ((send = rc_avpair_readin(rh, stdin))) {
+
+		username = service = type = "(unknown)";
+		fproto = NULL;
+
+		if ((vp = rc_avpair_get(send, PW_ACCT_STATUS_TYPE, 0)) != NULL)
+				if ((dval = rc_dict_getval(rh, vp->lvalue, vp->name)) != NULL) {
+					type = dval->name;
+				}
+
+		if ((vp = rc_avpair_get(send, PW_USER_NAME, 0)) != NULL)
+				username = vp->strvalue;
+
+		if ((vp = rc_avpair_get(send, PW_SERVICE_TYPE, 0)) != NULL)
+				if ((dval = rc_dict_getval(rh, vp->lvalue, vp->name)) != NULL) {
+					service = dval->name;
+				}
+
+		if (vp && (vp->lvalue == PW_FRAMED) &&
+			((vp = rc_avpair_get(send, PW_FRAMED_PROTOCOL, 0)) != NULL))
+				if ((dval = rc_dict_getval(rh, vp->lvalue, vp->name)) != NULL) {
+					fproto = dval->name;
+				}
+
+		result = rc_acct(rh, client_port, send);
+		if (result == OK_RC)
+		{
+			fprintf(stderr, SC_ACCT_OK);
+			rc_log(LOG_NOTICE, "accounting OK, type %s, username %s, service %s%s%s",
+				   type, username, service,(fproto)?"/":"", (fproto)?fproto:"");
+		}
+		else
+		{
+			fprintf(stderr, SC_ACCT_FAILED, result);
+			rc_log(LOG_NOTICE, "accounting FAILED, type %s, username %s, service %s%s%s",
+				   type, username, service,(fproto)?"/":"", (fproto)?fproto:"");
+		}
+		rc_avpair_free(send);
+	}
+
+	exit (result);
+}

+ 156 - 0
thirdparty/FreeRadius/src/radembedded.c

@@ -0,0 +1,156 @@
+/*
+ * radembedded.c - a sample c program showing how to embed the configuration of a radius
+ * client, using the FreeRADIUS Client Library without an external configuration file.
+ */
+
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <syslog.h>
+#include <freeradius-client.h>
+
+
+int
+main (int argc, char **argv)
+{
+	int		retval = 0;
+	rc_handle 	*rh = NULL;
+
+	uint32_t 		client_port = 0;
+	uint32_t		status_type = PW_STATUS_STOP; 
+        VALUE_PAIR      *send = NULL;
+	char		username[255] = "bob@somedomain.here";
+	char		callfrom[255] = "8475551212";
+	char		callto[255] = "8479630116";
+	char		myuuid[255] = "981743-asdf-90834klj234";
+
+	/* Initialize the 'rh' structure */
+
+	rh = rc_new();
+	if (rh == NULL) 
+	{
+		printf("ERROR: Failed to allocate initial structure\n");
+		exit(1);
+	}
+
+	/* Initialize the config structure */
+
+	rh = rc_config_init(rh);
+	if (rh == NULL)
+	{
+		printf("ERROR: Failed to initialze configuration\n");
+		exit(1);
+	}
+
+	/* 
+	 * Set the required options for configuration
+	 */
+
+	/* set auth_order to be radius only */
+
+	if (rc_add_config(rh, "auth_order", "radius", "config", 0) != 0) 
+	{
+		printf("ERROR: Unable to set auth_order.\n");
+		rc_destroy(rh);
+		exit(1);
+	}
+
+	if (rc_add_config(rh, "login_tries", "4", "config", 0) != 0) 
+	{
+		printf("ERROR: Unable to set login_tries.\n");
+		rc_destroy(rh);
+		exit(1);
+	}
+
+	if (rc_add_config(rh, "dictionary", "/usr/local/radius/dictionary", "config", 0) != 0)
+	{
+		printf("ERROR: Unable to set dictionary.\n");
+		rc_destroy(rh);
+		exit(1);
+	}
+	
+	if (rc_add_config(rh, "radius_retries", "3", "config", 0) != 0) 
+	{
+		printf("ERROR: Unable to set radius_retries.\n");
+		rc_destroy(rh);
+		exit(1);
+	}
+
+	if (rc_add_config(rh, "radius_timeout", "5", "config", 0) != 0) 
+	{
+		printf("ERROR: Unable to set radius_timeout.\n");
+		rc_destroy(rh);
+		exit(1);
+	}
+
+	/* auth/acct servers are added in the form: host[:port[:secret]]
+	 * If you don't set the secret via the add_config option, you must set a 'servers'
+         * entry to specify the location of the 'servers' file which stores the secrets to
+         * be used.
+         */
+
+	if (rc_add_config(rh, "authserver", "localhost::testing123", "config", 0) != 0) 
+	{
+		printf("ERROR: Unable to set authserver.\n");
+		rc_destroy(rh);
+		exit(1);
+	}
+
+	if (rc_add_config(rh, "acctserver", "localhost:1813:testing123", "config", 0) != 0) 
+	{
+		printf("ERROR: Unable to set acctserver.\n");
+		rc_destroy(rh);
+		exit(1);
+	}
+
+	/* Done setting configuration items */
+	
+	/* Read in the dictionary file(s) */
+
+	if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0) 
+	{
+		printf("ERROR: Failed to initialize radius dictionary\n");
+		exit(1);
+	}
+
+        if (rc_avpair_add(rh, &send, PW_ACCT_STATUS_TYPE, &status_type, -1, 0) == NULL)
+	{	
+		printf("ERROR: Failed adding Acct-Status-Type: to %d\n", status_type);		
+                exit(1);
+	}
+        if (rc_avpair_add(rh, &send, PW_ACCT_SESSION_ID, myuuid, -1, 0) == NULL)
+	{	
+		printf("ERROR: Failed adding Acct-Session-ID: to %s\n", myuuid);		
+                exit(1);
+	}
+        if (rc_avpair_add(rh, &send, PW_USER_NAME, username, -1, 0) == NULL)
+	{	
+		printf("ERROR: Failed adding User-Name: to %s\n", username);		
+                exit(1);
+	}
+        if (rc_avpair_add(rh, &send, PW_CALLED_STATION_ID, callto, -1, 0) == NULL)
+	{	
+		printf("ERROR: Failed adding Called-Station-ID: to %s\n", callto);		
+                exit(1);
+	}
+        if (rc_avpair_add(rh, &send, PW_CALLING_STATION_ID, callfrom, -1, 0) == NULL)
+	{	
+		printf("ERROR: Failed adding Calling-Station-ID: to %s\n", callfrom);		
+                exit(1);
+	}
+
+	if(rc_acct(rh, client_port, send) == OK_RC)
+	{
+		printf("INFO: Accounting OK: %s\n", username);
+		retval = 0;
+	}
+	else
+	{
+		printf("INFO: Accounting Failed: %s\n", username);
+		retval = -1;
+	}
+	rc_destroy(rh);
+	rc_avpair_free(send);
+
+	exit(retval);
+}

+ 96 - 0
thirdparty/FreeRadius/src/radexample.c

@@ -0,0 +1,96 @@
+/*
+ * $Id: radexample.c,v 1.8 2007/07/11 17:29:30 cparker Exp $
+ *
+ * Copyright (C) 1995,1996,1997 Lars Fenneberg
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+
+static char	rcsid[] =
+		"$Id: radexample.c,v 1.8 2007/07/11 17:29:30 cparker Exp $";
+
+#include	<config.h>
+#include	<includes.h>
+#include	<freeradius-client.h>
+#include	<pathnames.h>
+
+static char *pname = NULL;
+
+int
+main (int argc, char **argv)
+{
+	int             result;
+	char		username[128];
+	char            passwd[AUTH_PASS_LEN + 1];
+	VALUE_PAIR 	*send, *received;
+	uint32_t		service;
+	char 		msg[PW_MAX_MSG_SIZE], username_realm[256];
+	char		*default_realm;
+	rc_handle	*rh;
+
+	pname = (pname = strrchr(argv[0],'/'))?pname+1:argv[0];
+
+	rc_openlog(pname);
+
+	if ((rh = rc_read_config(RC_CONFIG_FILE)) == NULL)
+		return ERROR_RC;
+
+	if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0)
+		return ERROR_RC;
+
+	default_realm = rc_conf_str(rh, "default_realm");
+
+	strncpy(username, rc_getstr (rh, "login: ",1), sizeof(username));
+	strncpy (passwd, rc_getstr(rh, "Password: ",0), sizeof (passwd));
+
+	send = NULL;
+
+	/*
+	 * Fill in User-Name
+	 */
+
+	strncpy(username_realm, username, sizeof(username_realm));
+
+	/* Append default realm */
+	if ((strchr(username_realm, '@') == NULL) && default_realm &&
+	    (*default_realm != '\0'))
+	{
+		strncat(username_realm, "@", sizeof(username_realm)-strlen(username_realm)-1);
+		strncat(username_realm, default_realm, sizeof(username_realm)-strlen(username_realm)-1);
+	}
+
+	if (rc_avpair_add(rh, &send, PW_USER_NAME, username_realm, -1, 0) == NULL)
+		return ERROR_RC;
+
+	/*
+	 * Fill in User-Password
+	 */
+
+	if (rc_avpair_add(rh, &send, PW_USER_PASSWORD, passwd, -1, 0) == NULL)
+		return ERROR_RC;
+
+	/*
+	 * Fill in Service-Type
+	 */
+
+	service = PW_AUTHENTICATE_ONLY;
+	if (rc_avpair_add(rh, &send, PW_SERVICE_TYPE, &service, -1, 0) == NULL)
+		return ERROR_RC;
+
+	result = rc_auth(rh, 0, send, &received, msg);
+
+	if (result == OK_RC)
+	{
+		fprintf(stderr, "\"%s\" RADIUS Authentication OK\n", username);
+	}
+	else
+	{
+		fprintf(stderr, "\"%s\" RADIUS Authentication failure (RC=%i)\n", username, result);
+	}
+
+	return result;
+}

+ 197 - 0
thirdparty/FreeRadius/src/radius.c

@@ -0,0 +1,197 @@
+/*
+ * $Id: radius.c,v 1.9 2007/07/11 17:29:30 cparker Exp $
+ *
+ * Copyright (C) 1996 Lars Fenneberg
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+#include <config.h>
+#include <includes.h>
+#include <freeradius-client.h>
+#include <messages.h>
+#include <radlogin.h>
+
+extern ENV *env;
+
+LFUNC auth_radius(rc_handle *rh, uint32_t client_port, char const *username, char const *passwd)
+{
+
+	VALUE_PAIR 	*send, *received, *vp, *service_vp;
+	uint32_t		service, ftype, ctype;
+	char 		msg[PW_MAX_MSG_SIZE], *p, username_realm[256];
+	char            name[2048], value[2048]; /* more than enough */
+	int		result;
+	char		*default_realm, *service_str, *ftype_str;
+	DICT_VALUE	*dval;
+
+	send = received = NULL;
+	memset(msg, 0, sizeof(msg));
+
+	/*
+	 * Determine and fill in Service-Type
+	 */
+
+	service = PW_LOGIN;
+	ftype = 0;
+	ctype = 0;
+
+	if (rc_avpair_add(rh, &send, PW_SERVICE_TYPE, &service, -1, 0) == NULL)
+		return NULL;
+
+	/* Fill in Framed-Protocol, if neccessary */
+
+	if (ftype != 0)
+	{
+		if (rc_avpair_add(rh, &send, PW_FRAMED_PROTOCOL, &ftype, -1, 0) == NULL)
+			return NULL;
+	}
+
+	/* Fill in Framed-Compression, if neccessary */
+
+	if (ctype != 0)
+	{
+		if (rc_avpair_add(rh, &send, PW_FRAMED_COMPRESSION, &ctype, -1, 0) == NULL)
+			return NULL;
+	}
+
+	/*
+	 * Fill in User-Name
+	 */
+
+	 strncpy(username_realm, username, sizeof(username_realm));
+
+	 /* Append default realm */
+	 default_realm = rc_conf_str(rh, "default_realm");
+
+	 if ((strchr(username_realm, '@') == NULL) && default_realm &&
+	     ((*default_realm) != '\0'))
+	 {
+		strncat(username_realm, "@", sizeof(username_realm)-strlen(username_realm)-1);
+		strncat(username_realm, default_realm, sizeof(username_realm)-strlen(username_realm)-1);
+	 }
+
+	if (rc_avpair_add(rh, &send, PW_USER_NAME, username_realm, -1, 0) == NULL)
+		return NULL;
+
+	/*
+	 * Fill in User-Password
+	 */
+
+	if (rc_avpair_add(rh, &send, PW_USER_PASSWORD, passwd, -1, 0) == NULL)
+		return NULL;
+
+	result = rc_auth(rh, client_port, send, &received, msg);
+
+	if (result == OK_RC)
+	{
+		/* Set up a running count of attributes saved. */
+		int acount[256], attr;
+
+		memset(acount, 0, sizeof(acount));
+
+		rc_add_env(env, "RADIUS_USER_NAME", username);
+
+		vp = received;
+
+		/* map-- keep track of the attributes so that we know
+		   when to add the delimiters. Note that we can only
+		   handle attributes < 256, which is the standard anyway. */
+
+		while (vp)
+		{
+			strcpy(name, "RADIUS_");
+			if (rc_avpair_tostr(rh, vp, name+7, sizeof(name)-7, value, sizeof(value)) < 0) {
+				rc_avpair_free(send);
+				rc_avpair_free(received);
+				return NULL;
+			}
+
+			/* Translate "-" => "_" and uppercase*/
+			for(p = name; *p; p++) {
+				*p = toupper(*p);
+				if (*p == '-') *p = '_';
+			}
+
+			/* Add to the attribute count and append the var
+			   if necessary. */
+			if ((attr = vp->attribute) < 256)
+			{
+				int count;
+				if ((count = acount[attr]++) > 0) {
+					char buf[10];
+					snprintf(buf, sizeof(buf), "_%d", count);
+					strcat(name,buf);
+				}
+			}
+
+			if (rc_add_env(env, name, value) < 0)
+			{
+				rc_avpair_free(send);
+				rc_avpair_free(received);
+				return NULL;
+			}
+
+			vp = vp->next;
+		}
+
+		service_str = "(unknown)";
+		ftype_str = NULL;
+
+		if ((service_vp = rc_avpair_get(received, PW_SERVICE_TYPE, 0)) != NULL)
+				if ((dval = rc_dict_getval(rh, service_vp->lvalue, service_vp->name)) != NULL) {
+					service_str = dval->name;
+				}
+
+		if (service_vp && (service_vp->lvalue == PW_FRAMED) &&
+			((vp = rc_avpair_get(received, PW_FRAMED_PROTOCOL, 0)) != NULL))
+				if ((dval = rc_dict_getval(rh, vp->lvalue, vp->name)) != NULL) {
+					ftype_str = dval->name;
+				}
+
+		rc_log(LOG_NOTICE, "authentication OK, username %s, service %s%s%s",
+				username, service_str,(ftype_str)?"/":"", (ftype_str)?ftype_str:"");
+
+		if (*msg != '\0')
+			printf(SC_SERVER_REPLY, msg);
+		else
+			printf(SC_RADIUS_OK);
+
+		rc_avpair_free(send);
+		rc_avpair_free(received);
+
+		return radius_login;
+	}
+	else
+	{
+		rc_log(LOG_NOTICE, "authentication FAILED, type RADIUS, username %s",
+			   username_realm);
+		if (*msg != '\0')
+			printf(SC_SERVER_REPLY, msg);
+		else
+			printf(SC_RADIUS_FAILED);
+	}
+
+	rc_avpair_free(send);
+	if (received)
+		rc_avpair_free(received);
+
+	return NULL;
+}
+
+void
+radius_login(rc_handle *rh, char const *username)
+{
+	char *login_radius = rc_conf_str(rh, "login_radius");
+
+	execle(login_radius, login_radius, NULL, env->env);
+
+	rc_log(LOG_ERR, "couldn't execute %s: %s", login_radius, strerror(errno));
+	fprintf(stderr, "couldn't execute %s: %s", login_radius, strerror(errno));
+
+	sleep(1);	/* give the user time to read */
+	exit(ERROR_RC);
+}

+ 183 - 0
thirdparty/FreeRadius/src/radiusclient.c

@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2004 Maxim Sobolev <sobomax@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: radiusclient.c,v 1.8 2010/02/04 10:30:26 aland Exp $
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <freeradius-client.h>
+
+#define BUF_LEN 4096
+
+int process(void *, VALUE_PAIR *, int, int);
+
+static void
+usage(void)
+{
+
+    fprintf(stderr, "usage: radiusclient [-f config_file] [-p nas_port] [-s | [-a] a1=v1 [a2=v2[...[aN=vN]...]]]\n");
+    exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+    int i, nas_port, ch, acct, server, ecount, firstline, theend;
+    void *rh;
+    size_t len;
+    VALUE_PAIR *send, **vp;
+    char *rc_conf, *cp;
+    char lbuf[4096];
+
+    rc_conf = RC_CONFIG_FILE;
+    nas_port = 5060;
+
+    acct = 0;
+    server = 0;
+    while ((ch = getopt(argc, argv, "af:p:s")) != -1) {
+        switch (ch) {
+        case 'f':
+            rc_conf = optarg;
+            break;
+
+        case 'p':
+            nas_port = atoi(optarg);
+            break;
+
+        case 'a':
+            acct = 1;
+            break;
+
+        case 's':
+            server = 1;
+            break;
+
+        default:
+            usage();
+        }
+    }
+    argc -= optind;
+    argv += optind;
+
+    if ((argc == 0 && server == 0) || (argc != 0 && server != 0))
+        usage();
+
+    if ((rh = rc_read_config(rc_conf)) == NULL) {
+        fprintf(stderr, "error opening radius configuration file\n");
+        exit(1);
+    }
+
+    if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0) {
+        fprintf(stderr, "error reading radius dictionary\n");
+        exit(2);
+    }
+
+    if (server == 0) {
+        send = NULL;
+        vp = &send;
+        for (i = 0; i < argc; i++) {
+            if (rc_avpair_parse(rh, argv[i], vp) < 0) {
+                fprintf(stderr, "%s: can't parse AV pair\n", argv[i]);
+                exit(3);
+            }
+            vp = &send->next;
+        }
+        exit(process(rh, send, acct, nas_port));
+    }
+    while (1 == 1) {
+        send = NULL;
+        vp = &send;
+        ecount = 0;
+        firstline = 1;
+        acct = 0;
+        do {
+            len = 0;
+            cp = rc_fgetln(stdin, &len);
+            theend = 1;
+            if (cp != NULL && len > 0) {
+                if (firstline != 0) {
+                    if (len >= 4 && memcmp(cp, "ACCT", 4) == 0)
+                        acct = 1;
+                    firstline = 0;
+                    theend = 0;
+                    continue;
+                }
+                for (i = 0; i < len; i++) {
+                    if (!isspace(cp[i])) {
+                        theend = 0;
+                        break;
+                    }
+                }
+                if (theend == 0) {
+                    memcpy(lbuf, cp, len);
+                    lbuf[len] = '\0';
+                    if (rc_avpair_parse(rh, lbuf, vp) < 0) {
+                        fprintf(stderr, "%s: can't parse AV pair\n", lbuf);
+                        ecount++;
+                    } else {
+                        vp = &send->next;
+                    }
+                }
+            }
+        } while (theend == 0);
+        if (send != NULL && ecount == 0)
+            printf("%d\n\n", process(rh, send, acct, nas_port));
+        else
+            printf("%d\n\n", -1);
+        fflush(stdout);
+        if (send != NULL)
+            rc_avpair_free(send);
+		if (cp == NULL || len == 0)
+            break;
+    }
+    exit(0);
+}
+
+int
+process(void *rh, VALUE_PAIR *send, int acct, int nas_port)
+{
+    VALUE_PAIR *received;
+    char msg[PW_MAX_MSG_SIZE];
+    char buf[BUF_LEN];
+    int i;
+
+    received = NULL;
+    if (acct == 0) {
+        i = rc_auth(rh, nas_port, send, &received, msg);
+        if (received != NULL) {
+            printf("%s", rc_avpair_log(rh, received, buf, BUF_LEN));
+            rc_avpair_free(received);
+        }
+    } else {
+        i = rc_acct(rh, nas_port, send);
+    }
+
+    return (i == OK_RC) ? 0 : 1;
+}

+ 388 - 0
thirdparty/FreeRadius/src/radlogin.c

@@ -0,0 +1,388 @@
+/*
+ * radlogin.c  RADIUS based /bin/login replacement
+ *
+ * Version:    $Id: radlogin.c,v 1.9 2008/01/09 07:04:18 sobomax Exp $
+ *
+ * Copyright (C) 1995,1996 Lars Fenneberg
+ * Copyright (C) 2007 The FreeRADIUS Project
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ *
+ */
+
+static char	rcsid[] =
+		"$Id: radlogin.c,v 1.9 2008/01/09 07:04:18 sobomax Exp $";
+
+#include	<config.h>
+#include	<includes.h>
+#include	<freeradius-client.h>
+#include	<messages.h>
+#include	<pathnames.h>
+#include	<radlogin.h>
+
+ENV *env = NULL;
+static char *pname = NULL;
+static rc_handle *rh = NULL;
+
+static RETSIGTYPE
+alarm_handler(int sn)
+{
+	fprintf(stderr, SC_TIMEOUT, rc_conf_int(rh, "login_timeout"));
+	sleep(1);
+	exit(ERROR_RC);
+}
+
+static int
+login_allowed(char *tty)
+{
+	FILE *fp;
+	char fname[PATH_MAX];
+	int c;
+
+	strcpy(fname, rc_conf_str(rh, "nologin"));
+	if (access(fname, F_OK) < 0) {
+		if (tty) {
+			snprintf(fname, sizeof(fname), "%s.%s", rc_conf_str(rh, "nologin"), tty);
+			if (access(fname, F_OK) < 0)
+				return 1;
+		} else {
+			return 1;
+		}
+	}
+
+	if ((fp = fopen(fname, "r")) != NULL)
+	{
+		while ((c = fgetc(fp)) != EOF)
+		{
+			if (c == '\n')
+				fputc('\r', stdout);
+			fputc(c, stdout);
+		}
+		fflush(stdout);
+		fclose(fp);
+	} else {
+		printf(SC_NOLOGIN);
+	}
+	return 0;
+}
+
+static char *
+subst_placeholders(char *str, char *tty)
+{
+	char *p,*q;
+	static char buf[4096];
+#if defined(HAVE_UNAME)
+	struct utsname uts;
+#endif
+#if !defined(HAVE_STRUCT_UTSNAME_DOMAINNAME) && defined(HAVE_GETDOMAINNAME)
+	char domainname[256];
+#endif
+
+#if defined(HAVE_UNAME)
+	uname(&uts);
+#endif
+
+	p = str;
+	q = buf;
+
+	while (*p != '\0') {
+		switch (*p) {
+			case '\\':
+				if (*(p+1) == '\0')
+					break;
+				p++;
+				switch (*p) {
+					case 'I':
+						strcpy(q, rcsid);
+						q += strlen(rcsid);
+						break;
+					case 'L':
+					case 'P':
+						strcpy(q, tty);
+						q += strlen(tty);
+						break;
+#if defined(HAVE_UNAME)
+					case 'S':
+						strcpy(q, uts.sysname);
+						q += strlen(uts.sysname);
+						break;
+					case 'N':
+						strcpy(q, uts.nodename);
+						q += strlen(uts.nodename);
+						break;
+					case 'R':
+						strcpy(q, uts.release);
+						q += strlen(uts.release);
+						break;
+					case 'V':
+						strcpy(q, uts.version);
+						q += strlen(uts.version);
+						break;
+					case 'M':
+						strcpy(q, uts.machine);
+						q += strlen(uts.machine);
+						break;
+#endif
+					case 'D':
+#if defined(HAVE_STRUCT_UTSNAME_DOMAINNAME)
+						strcpy(q, uts.domainname);
+						q += strlen(uts.domainname);
+#elif defined(HAVE_GETDOMAINNAME)
+						getdomainname(domainname, sizeof(domainname));
+						strcpy(q, domainname);
+						q += strlen(domainname);
+#endif
+						break;
+					case '\\':
+						*q = '\\';
+						q++;
+						break;
+				}
+				break;
+#if defined(HAVE_UNAME)
+			case '@':
+				strcpy(q, uts.nodename);
+				q += strlen(uts.nodename);
+				break;
+#endif
+			case '\n':
+				strcpy(q,"\r\n");
+				q += 2;
+				break;
+			default:
+				*q = *p;
+				q++;
+				break;
+		}
+
+		p++;
+	}
+	*q = '\0';
+
+	return buf;
+}
+
+static void
+usage(void)
+{
+	fprintf(stderr,"Usage: %s [-Vhnd] [-f <config_file>] [-i <client_port>] [-m <login_tries>]\n\n", pname);
+	fprintf(stderr,"  -V		output version information\n");
+	fprintf(stderr,"  -h		output this text\n");
+	fprintf(stderr,"  -n		don't display issue file\n");
+	fprintf(stderr,"  -f		filename of alternate config file\n");
+	fprintf(stderr,"  -i		ttyname to send to the server\n");
+	fprintf(stderr,"  -m		maximum login tries (overrides value in config file)\n");
+        exit(ERROR_RC);
+}
+
+static void
+version(void)
+{
+	fprintf(stderr,"%s: %s\n", pname ,rcsid);
+	exit(ERROR_RC);
+}
+
+int
+main (int argc, char **argv)
+{
+	char		username[128];
+	char		passwd[AUTH_PASS_LEN + 1];
+	int 		tries, remaining, c;
+	uint32_t		client_port;
+	void 		(*login_func)(rc_handle *, char const *);
+	FILE		*fp;
+	char 		buf[4096];
+	char		tty[1024], *p;
+	int		noissue = 0;
+	int		maxtries = 0;
+	char		*ttyn  = NULL;
+	char            *path_radiusclient_conf = RC_CONFIG_FILE;
+
+        extern char *optarg;
+        extern int optind;
+
+	pname = (pname = strrchr(argv[0],'/'))?pname+1:argv[0];
+
+	rc_openlog(pname);
+
+	while ((c = getopt(argc,argv,"f:m:i:nhV")) > 0)
+	{
+		switch(c) {
+			case 'f':
+				path_radiusclient_conf = optarg;
+				break;
+			case 'i':
+				ttyn = optarg;
+				break;
+			case 'n':
+				noissue = 1;
+				break;
+			case 'm':
+				maxtries = atoi(optarg);
+				break;
+			case 'V':
+				version();
+				break;
+			case 'h':
+				usage();
+				break;
+			default:
+				exit(ERROR_RC);
+				break;
+		}
+	}
+
+	if ((rh = rc_read_config(path_radiusclient_conf)) == NULL)
+		exit(ERROR_RC);
+
+	if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0)
+		exit (ERROR_RC);
+
+	if (rc_read_mapfile(rh, rc_conf_str(rh, "mapfile")) != 0)
+		exit (ERROR_RC);
+
+	if (ttyn != NULL)
+	{
+		client_port = rc_map2id(rh, ttyn);
+
+		if ((p = strrchr(ttyn, '/')) == NULL)
+			strncpy(tty, ttyn, sizeof(tty));
+		else
+			strncpy(tty, p+1, sizeof(tty));
+	}
+	else
+	{
+		ttyn = ttyname(0);
+		if (ttyn)
+		{
+			if ((p = strrchr(ttyn, '/')) == NULL)
+				strncpy(tty, ttyn, sizeof(tty));
+			else
+				strncpy(tty, p+1, sizeof(tty));
+
+			client_port = rc_map2id(rh, ttyn);
+		}
+		else
+		{
+			*tty = '\0';
+			client_port = 0;
+		}
+	}
+
+#ifdef SETVBUF_REVERSED
+	setvbuf(stdout, _IONBF, NULL, 0);
+#else
+	setvbuf(stdout, NULL, _IONBF, 0);
+#endif
+
+	if ((argc - optind) == 1)
+	{
+		strncpy(username,argv[optind], sizeof(username));
+	}
+	else
+	{
+		*username = '\0';
+
+		if (!noissue) {
+			if (rc_conf_str(rh, "issue") && ((fp = fopen(rc_conf_str(rh, "issue"), "r")) != NULL))
+			{
+				while (fgets(buf, sizeof(buf), fp) != NULL)
+					fputs(subst_placeholders(buf, tty), stdout);
+
+				fflush(stdout);
+				fclose(fp);
+			} else {
+				fputs(subst_placeholders(SC_DEFAULT_ISSUE, tty), stdout);
+				fflush(stdout);
+			}
+		}
+	}
+
+	if ((env = rc_new_env(ENV_SIZE)) == NULL)
+	{
+		rc_log(LOG_CRIT, "rc_new_env: FATAL: out of memory");
+		abort();
+	}
+
+#ifdef SECURITY_DISABLED
+	if (rc_import_env(env,environ) < 0)
+	{
+		rc_log(LOG_CRIT, "rc_import_env: FATAL: not enough space for environment (increase ENV_SIZE)");
+		abort();
+	}
+#else
+	rc_add_env(env, "IFS", " ");
+	rc_add_env(env, "PATH", RC_SECURE_PATH);
+#endif
+
+	signal(SIGALRM, alarm_handler);
+
+	remaining = rc_conf_int(rh, "login_timeout");
+
+	if (!maxtries)
+		maxtries = rc_conf_int(rh, "login_tries");
+
+	tries = 1;
+	while (tries <= maxtries)
+	{
+	 alarm(remaining);
+
+	 while (!*username) {
+	 	p = rc_getstr (rh, SC_LOGIN, 1);
+	 	if (p)
+	 		strncpy(username, p, sizeof(username));
+	 	else
+	 		exit (ERROR_RC);
+	 }
+	 p = rc_getstr(rh, SC_PASSWORD,0);
+	 if (p)
+	 	strncpy (passwd, p, sizeof (passwd));
+	 else
+		exit (ERROR_RC);
+
+	 remaining = alarm(0);
+
+	 login_func = NULL;
+
+ 	 if (rc_conf_int(rh, "auth_order") & AUTH_LOCAL_FST)
+ 	 {
+ 	 	login_func = auth_local(username, passwd);
+
+ 	 	if (!login_func)
+ 	 		if (rc_conf_int(rh, "auth_order") & AUTH_RADIUS_SND)
+ 	 			login_func = auth_radius(rh, client_port, username, passwd);
+ 	 }
+ 	 else
+ 	 {
+		login_func = auth_radius(rh, client_port, username, passwd);
+ 	 	if (!login_func)
+ 	 		if (rc_conf_int(rh, "auth_order") & AUTH_LOCAL_SND)
+ 	 			login_func = auth_local(username, passwd);
+ 	 }
+
+	 memset(passwd, '\0', sizeof(passwd));
+
+	 if (login_func != NULL) {
+	 	if (login_allowed(tty)) {
+	 		(*login_func)(rh, username);
+		} else {
+			sleep(1);
+			exit (ERROR_RC);
+		}
+	}
+
+	 *username = '\0';
+
+	 if ((++tries) <= maxtries) {
+		alarm(remaining);
+	 	sleep(tries * 2);
+	 	remaining = alarm(0);
+	 }
+
+	}
+
+	fprintf(stderr, SC_EXCEEDED);
+	sleep(1);
+
+	exit (ERROR_RC);
+}

+ 25 - 0
thirdparty/FreeRadius/src/radlogin.h

@@ -0,0 +1,25 @@
+/*
+ * $Id: radlogin.h,v 1.4 2007/07/11 17:29:31 cparker Exp $
+ *
+ * Copyright (C) 1996 Lars Fenneberg
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+#ifndef RADLOGIN_H
+#define RADLOGIN_H
+
+typedef void (*LFUNC)(rc_handle *, char const *);
+
+/* radius.c */
+LFUNC auth_radius(rc_handle *, uint32_t, char const *, char const *);
+void radius_login(rc_handle *, char const *);
+
+/* local.c */
+LFUNC auth_local(char const *, char const *);
+void local_login(rc_handle *, char const *);
+
+#endif /* RADLOGIN_H */

+ 130 - 0
thirdparty/FreeRadius/src/radstatus.c

@@ -0,0 +1,130 @@
+/*
+ * $Id: radstatus.c,v 1.8 2007/04/13 14:20:44 pnixon Exp $
+ *
+ * Copyright (C) 1995,1996 Lars Fenneberg
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+/* FIX ME FIX ME FIX ME
+ * This is broken, now that send_server requires the secret to be passed
+ * It will need to be collected as an additional argument on command line
+ */
+
+#define FIX_ME_SECRET "fixme"
+
+static char	rcsid[] =
+		"$Id: radstatus.c,v 1.8 2007/04/13 14:20:44 pnixon Exp $";
+
+#include <config.h>
+#include <includes.h>
+#include <freeradius-client.h>
+#include <pathnames.h>
+#include <messages.h>
+
+static char *pname;
+
+
+void usage(void)
+{
+	fprintf(stderr,"Usage: %s [-Vh] [-f <config_file>] [server[:port[:secret]] ...\n\n", pname);
+	fprintf(stderr,"  -V            output version information\n");
+	fprintf(stderr,"  -h            output this text\n");
+	fprintf(stderr,"  -f		filename of alternate config file\n");
+	exit(ERROR_RC);
+}
+
+void version(void)
+{
+	fprintf(stderr,"%s: %s\n", pname ,rcsid);
+	exit(ERROR_RC);
+}
+
+int main (int argc, char **argv)
+{
+	int	result = ERROR_RC;
+   	int	c,i;
+	char	*p, msg[PW_MAX_MSG_SIZE];
+	SERVER	*srv;
+	char	*path_radiusclient_conf = RC_CONFIG_FILE;
+	rc_handle *rh;
+
+	extern int optind;
+
+	pname = (pname = strrchr(argv[0],'/'))?pname+1:argv[0];
+
+	rc_openlog(pname);
+
+	while ((c = getopt(argc,argv,"hVf:")) > 0)
+	{
+		switch(c) {
+			case 'f':
+				path_radiusclient_conf = optarg;
+				break;
+			case 'V':
+				version();
+				break;
+			case 'h':
+				usage();
+				break;
+			default:
+				exit(ERROR_RC);
+				break;
+		}
+	}
+
+	argc -= optind;
+	argv += optind;
+
+	if ((rh = rc_read_config(path_radiusclient_conf)) == NULL)
+		exit(ERROR_RC);
+
+	if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0)
+		exit (ERROR_RC);
+
+	if (argc > 0) {
+		for (i = 0; i < argc; i++) {
+			if ((p = strchr(argv[i], ':')) == NULL) {
+				result = rc_check(rh, argv[i],FIX_ME_SECRET,rc_getport(AUTH), msg);
+			} else if (!strcmp(p+1, "auth")) {
+				*p = '\0';
+				result = rc_check(rh, argv[i],FIX_ME_SECRET,rc_getport(AUTH), msg);
+			} else if (!strcmp(p+1, "acct")) {
+				*p = '\0';
+				result = rc_check(rh, argv[i],FIX_ME_SECRET,rc_getport(ACCT), msg);
+			} else {
+				*p = '\0';
+				result = rc_check(rh, argv[i],FIX_ME_SECRET,atoi(p+1), msg);
+			}
+			if (result == OK_RC)
+				fputs(msg, stdout);
+			else
+				printf(SC_STATUS_FAILED);
+		}
+	} else {
+		srv = rc_conf_srv(rh, "authserver");
+		for(i=0; i<srv->max ; i++)
+		{
+			result = rc_check(rh, srv->name[i], srv->secret[i], srv->port[i], msg);
+			if (result == OK_RC)
+				fputs(msg, stdout);
+			else
+				printf(SC_STATUS_FAILED);
+		}
+
+		srv = rc_conf_srv(rh, "acctserver");
+		for(i=0; i<srv->max ; i++)
+		{
+			result = rc_check(rh, srv->name[i], srv->secret[i], srv->port[i], msg);
+			if (result == OK_RC)
+				fputs(msg, stdout);
+			else
+				printf(SC_STATUS_FAILED);
+		}
+	}
+
+	return 0;
+}

+ 3 - 0
user/init_task.c

@@ -35,6 +35,7 @@
 //#include "ups_params.h"
 //#include "ups_monitor.h"
 //#include <lwip/stats.h>
+#include "radius_user.h"
 
 #ifdef PRINTF_STDLIB
 #include <stdio.h>
@@ -188,6 +189,8 @@ void InitTask(void *params)
   vTaskDelay(4000);
  
   SETTINGS_ResetBootTry();
+
+  RD_TestInit();
   
   // Отправка трапа о перезагрузке в случае статического IP
  /* if (!dhcp)

+ 1 - 1
user/main.h

@@ -58,7 +58,7 @@
 #define __packed		__attribute__(( packed ))
 #endif
    
-#define DEBUG
+//#define DEBUG
 
 #ifdef DEBUG
 #define DBG