2 * Copyright (C) 2013 Endian srl
3 * Author: Andrea Bonomi - <a.bonomi@endian.com>
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 #include "xauth_pam_listener.h"
32 #include <security/pam_appl.h>
34 typedef struct private_xauth_pam_listener_t private_xauth_pam_listener_t
;
37 * Private data of an xauth_pam_listener_t object.
39 struct private_xauth_pam_listener_t
{
42 * Public xauth_pam_listener_t interface.
44 xauth_pam_listener_t
public;
53 * PAM conv callback function
55 static int conv(int num_msg
, const struct pam_message
**msg
,
56 struct pam_response
**resp
, void *data
)
60 for (i
= 0; i
< num_msg
; i
++)
62 /* ignore any text info, but fail on any interaction request */
63 if (msg
[i
]->msg_style
!= PAM_TEXT_INFO
)
71 METHOD(listener_t
, ike_updown
, bool,
72 private_xauth_pam_listener_t
*this, ike_sa_t
*ike_sa
, bool up
)
74 struct pam_conv null_conv
= {
77 pam_handle_t
*pamh
= NULL
;
81 if (asprintf(&user
, "%Y", ike_sa
->get_other_eap_id(ike_sa
)) != -1)
83 ret
= pam_start(this->service
, user
, &null_conv
, &pamh
);
84 if (ret
== PAM_SUCCESS
)
88 ret
= pam_open_session(pamh
, 0);
89 if (ret
!= PAM_SUCCESS
)
91 DBG1(DBG_IKE
, "XAuth pam_open_session for '%s' failed: %s",
92 user
, pam_strerror(pamh
, ret
));
97 ret
= pam_close_session(pamh
, 0);
98 if (ret
!= PAM_SUCCESS
)
100 DBG1(DBG_IKE
, "XAuth pam_close_session for '%s' failed: %s",
101 user
, pam_strerror(pamh
, ret
));
107 DBG1(DBG_IKE
, "XAuth pam_start for '%s' failed: %s",
108 user
, pam_strerror(pamh
, ret
));
116 METHOD(xauth_pam_listener_t
, listener_destroy
, void,
117 private_xauth_pam_listener_t
*this)
122 xauth_pam_listener_t
*xauth_pam_listener_create()
124 private_xauth_pam_listener_t
*this;
129 .ike_updown
= _ike_updown
,
131 .destroy
= _listener_destroy
,
133 /* Look for PAM service, with a legacy fallback for the eap-gtc plugin.
134 * Default to "login". */
135 .service
= lib
->settings
->get_str(lib
->settings
,
136 "%s.plugins.xauth-pam.pam_service",
137 lib
->settings
->get_str(lib
->settings
,
138 "%s.plugins.eap-gtc.pam_service",
139 "login", charon
->name
),
143 return &this->public;