diff --git a/src/auth/gssapi.c b/src/auth/gssapi.c index 329510f1..b2fa1c68 100644 --- a/src/auth/gssapi.c +++ b/src/auth/gssapi.c @@ -208,7 +208,7 @@ static int verify_krb5_constraints(struct gssapi_ctx_st *pctx, gss_OID mech_type return 0; } -static int gssapi_auth_init(void **ctx, void *pool, const char *spnego, const char *ip, unsigned pid) +static int gssapi_auth_init(void **ctx, void *pool, const char *spnego, const char *ip, const char *our_ip, unsigned pid) { struct gssapi_ctx_st *pctx; OM_uint32 minor, flags, time; diff --git a/src/auth/pam.c b/src/auth/pam.c index b9761966..c4decee4 100644 --- a/src/auth/pam.c +++ b/src/auth/pam.c @@ -141,7 +141,7 @@ wait: } } -static int pam_auth_init(void** ctx, void *pool, const char* user, const char* ip, unsigned pid) +static int pam_auth_init(void** ctx, void *pool, const char* user, const char* ip, const char *our_ip, unsigned pid) { int pret; struct pam_ctx_st * pctx; diff --git a/src/auth/plain.c b/src/auth/plain.c index 890fb63b..29f00495 100644 --- a/src/auth/plain.c +++ b/src/auth/plain.c @@ -181,7 +181,7 @@ static int read_auth_pass(struct plain_ctx_st *pctx) return ret; } -static int plain_auth_init(void **ctx, void *pool, const char *username, const char *ip, unsigned pid) +static int plain_auth_init(void **ctx, void *pool, const char *username, const char *ip, const char *our_ip, unsigned pid) { struct plain_ctx_st *pctx; int ret; diff --git a/src/auth/radius.c b/src/auth/radius.c index 0ccb0685..4ecff09a 100644 --- a/src/auth/radius.c +++ b/src/auth/radius.c @@ -87,7 +87,7 @@ static void radius_global_deinit() rc_destroy(rh); } -static int radius_auth_init(void **ctx, void *pool, const char *username, const char *ip, unsigned id) +static int radius_auth_init(void **ctx, void *pool, const char *username, const char *ip, const char *our_ip, unsigned id) { struct radius_ctx_st *pctx; char *default_realm; @@ -104,6 +104,8 @@ static int radius_auth_init(void **ctx, void *pool, const char *username, const strlcpy(pctx->username, username, sizeof(pctx->username)); strlcpy(pctx->remote_ip, ip, sizeof(pctx->remote_ip)); + if (our_ip) + strlcpy(pctx->our_ip, our_ip, sizeof(pctx->our_ip)); pctx->pass_msg = pass_msg_first; default_realm = rc_conf_str(rh, "default_realm"); @@ -191,6 +193,7 @@ static int radius_auth_pass(void *ctx, const char *pass, unsigned pass_len) char txt[64]; int ret; + /* send Access-Request */ syslog(LOG_DEBUG, "radius-auth: communicating username (%s) and password", pctx->username); if (rc_avpair_add(rh, &send, PW_USER_NAME, pctx->username, -1, 0) == NULL) { syslog(LOG_ERR, @@ -207,6 +210,16 @@ static int radius_auth_pass(void *ctx, const char *pass, unsigned pass_len) goto cleanup; } + if (pctx->our_ip[0] != 0) { + struct sockaddr_storage st; + + if (inet_pton(AF_INET, pctx->our_ip, &st) != 0) { + rc_avpair_add(rh, &send, PW_NAS_IP_ADDRESS, (char*)&st, -1, 0); + } else if (inet_pton(AF_INET6, pctx->our_ip, &st) != 0) { + rc_avpair_add(rh, &send, PW_NAS_IPV6_ADDRESS, (char*)&st, -1, 0); + } + } + if (nas_identifier[0] != 0) { if (rc_avpair_add(rh, &send, PW_NAS_IDENTIFIER, nas_identifier, -1, 0) == NULL) { syslog(LOG_ERR, diff --git a/src/auth/radius.h b/src/auth/radius.h index 94ad6fed..a91c7808 100644 --- a/src/auth/radius.h +++ b/src/auth/radius.h @@ -29,6 +29,7 @@ struct radius_ctx_st { char groupname[MAX_GROUPNAME_SIZE]; char remote_ip[MAX_IP_STR]; + char our_ip[MAX_IP_STR]; int interim_interval_secs; /* variables for configuration */ diff --git a/src/ipc.proto b/src/ipc.proto index 4e59733d..20803771 100644 --- a/src/ipc.proto +++ b/src/ipc.proto @@ -189,6 +189,7 @@ message sec_auth_init_msg optional string hostname = 7; required string ip = 8; required uint32 auth_type = 9 [default = 0]; + optional string our_ip = 10; } /* SEC_AUTH_CONT */ diff --git a/src/sec-mod-auth.c b/src/sec-mod-auth.c index 1fa4be39..8633a2a7 100644 --- a/src/sec-mod-auth.c +++ b/src/sec-mod-auth.c @@ -711,7 +711,7 @@ int set_module(sec_mod_st * sec, client_entry_st *e, unsigned auth_type) return -1; } -int handle_sec_auth_init(int cfd, sec_mod_st * sec, const SecAuthInitMsg * req, pid_t pid) +int handle_sec_auth_init(int cfd, sec_mod_st *sec, const SecAuthInitMsg *req, pid_t pid) { int ret = -1; client_entry_st *e; @@ -735,7 +735,7 @@ int handle_sec_auth_init(int cfd, sec_mod_st * sec, const SecAuthInitMsg * req, if (e->module) { ret = - e->module->auth_init(&e->auth_ctx, e, req->user_name, req->ip, pid); + e->module->auth_init(&e->auth_ctx, e, req->user_name, req->ip, req->our_ip, pid); if (ret == ERR_AUTH_CONTINUE) { need_continue = 1; } else if (ret < 0) { diff --git a/src/sec-mod-auth.h b/src/sec-mod-auth.h index 0af83510..e7fdc909 100644 --- a/src/sec-mod-auth.h +++ b/src/sec-mod-auth.h @@ -32,7 +32,7 @@ typedef struct auth_mod_st { unsigned int allows_retries; /* whether the module allows retries of the same password */ void (*global_init)(void *pool, void* additional); void (*global_deinit)(void); - int (*auth_init)(void** ctx, void *pool, const char* username, const char* ip, unsigned id); + int (*auth_init)(void** ctx, void *pool, const char* username, const char *remote_ip, const char *our_ip, unsigned id); int (*auth_msg)(void* ctx, void *pool, char** msg); int (*auth_pass)(void* ctx, const char* pass, unsigned pass_len); int (*auth_group)(void* ctx, const char *suggested, char *groupname, int groupname_size); diff --git a/src/worker-auth.c b/src/worker-auth.c index 39cc6fb2..155be66b 100644 --- a/src/worker-auth.c +++ b/src/worker-auth.c @@ -1174,6 +1174,26 @@ int basic_auth_handler(worker_st * ws, unsigned http_ver, const char *msg) return ret; } +#if defined(__FreeBSD__) || defined(__OpenBSD__) +# define gsocklen int +#else +# define gsocklen socklen_t +#endif + +static char *get_our_ip(int fd, char str[MAX_IP_STR]) +{ + int ret; + struct sockaddr_storage sockaddr; + gsocklen socklen; + + socklen = sizeof(sockaddr); + ret = getsockname(fd, (struct sockaddr*)&sockaddr, &socklen); + if (ret == -1) + return NULL; + + return human_addr2((struct sockaddr*)&sockaddr, socklen, str, MAX_IP_STR, 0); +} + #define USERNAME_FIELD "username" #define PASSWORD_FIELD "password" #define GROUPNAME_FIELD "group%5flist" @@ -1193,6 +1213,7 @@ int post_auth_handler(worker_st * ws, unsigned http_ver) char *username = NULL; char *password = NULL; char *groupname = NULL; + char our_ip_str[MAX_IP_STR]; char *msg = NULL; unsigned def_group = 0; @@ -1291,6 +1312,7 @@ int post_auth_handler(worker_st * ws, unsigned http_ver) ireq.hostname = req->hostname; ireq.ip = ws->remote_ip_str; + ireq.our_ip = get_our_ip(ws->conn_fd, our_ip_str); sd = connect_to_secmod(ws); if (sd == -1) {