]> git.ipfire.org Git - people/ms/strongswan.git/blob - src/libcharon/plugins/xauth_pam/xauth_pam_listener.c
1b9c045c7249a2f6a20804d21558001de5df9135
[people/ms/strongswan.git] / src / libcharon / plugins / xauth_pam / xauth_pam_listener.c
1 /*
2 * Copyright (C) 2013 Endian srl
3 * Author: Andrea Bonomi - <a.bonomi@endian.com>
4 *
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:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
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
21 * THE SOFTWARE.
22 */
23
24 #define _GNU_SOURCE
25 #include <stdio.h>
26
27 #include "xauth_pam_listener.h"
28
29 #include <daemon.h>
30 #include <library.h>
31
32 #include <security/pam_appl.h>
33
34 typedef struct private_xauth_pam_listener_t private_xauth_pam_listener_t;
35
36 /**
37 * Private data of an xauth_pam_listener_t object.
38 */
39 struct private_xauth_pam_listener_t {
40
41 /**
42 * Public xauth_pam_listener_t interface.
43 */
44 xauth_pam_listener_t public;
45
46 /**
47 * PAM service
48 */
49 char *service;
50 };
51
52 /**
53 * PAM conv callback function
54 */
55 static int conv(int num_msg, const struct pam_message **msg,
56 struct pam_response **resp, void *data)
57 {
58 int i;
59
60 for (i = 0; i < num_msg; i++)
61 {
62 /* ignore any text info, but fail on any interaction request */
63 if (msg[i]->msg_style != PAM_TEXT_INFO)
64 {
65 return PAM_CONV_ERR;
66 }
67 }
68 return PAM_SUCCESS;
69 }
70
71 METHOD(listener_t, ike_updown, bool,
72 private_xauth_pam_listener_t *this, ike_sa_t *ike_sa, bool up)
73 {
74 struct pam_conv null_conv = {
75 .conv = conv,
76 };
77 pam_handle_t *pamh = NULL;
78 char *user;
79 int ret;
80
81 if (asprintf(&user, "%Y", ike_sa->get_other_eap_id(ike_sa)) != -1)
82 {
83 ret = pam_start(this->service, user, &null_conv, &pamh);
84 if (ret == PAM_SUCCESS)
85 {
86 if (up)
87 {
88 ret = pam_open_session(pamh, 0);
89 if (ret != PAM_SUCCESS)
90 {
91 DBG1(DBG_IKE, "XAuth pam_open_session for '%s' failed: %s",
92 user, pam_strerror(pamh, ret));
93 }
94 }
95 else
96 {
97 ret = pam_close_session(pamh, 0);
98 if (ret != PAM_SUCCESS)
99 {
100 DBG1(DBG_IKE, "XAuth pam_close_session for '%s' failed: %s",
101 user, pam_strerror(pamh, ret));
102 }
103 }
104 }
105 else
106 {
107 DBG1(DBG_IKE, "XAuth pam_start for '%s' failed: %s",
108 user, pam_strerror(pamh, ret));
109 }
110 pam_end(pamh, ret);
111 free(user);
112 }
113 return TRUE;
114 }
115
116 METHOD(xauth_pam_listener_t, listener_destroy, void,
117 private_xauth_pam_listener_t *this)
118 {
119 free(this);
120 }
121
122 xauth_pam_listener_t *xauth_pam_listener_create()
123 {
124 private_xauth_pam_listener_t *this;
125
126 INIT(this,
127 .public = {
128 .listener = {
129 .ike_updown = _ike_updown,
130 },
131 .destroy = _listener_destroy,
132 },
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),
140 charon->name),
141 );
142
143 return &this->public;
144 }