Line data Source code
1 : /*
2 : Authors:
3 : Sumit Bose <sbose@redhat.com>
4 :
5 : PAM client - create message blob
6 :
7 : Copyright (C) 2015 Red Hat
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU Lesser General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU Lesser General Public License for more details.
18 :
19 : You should have received a copy of the GNU Lesser General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include <stdlib.h>
24 : #include <security/pam_modules.h>
25 :
26 : #include "sss_pam_compat.h"
27 : #include "sss_pam_macros.h"
28 :
29 : #include "pam_message.h"
30 :
31 : #include "sss_cli.h"
32 :
33 94 : static size_t add_authtok_item(enum pam_item_type type,
34 : enum sss_authtok_type authtok_type,
35 : const char *tok, const size_t size,
36 : uint8_t *buf)
37 : {
38 94 : size_t rp = 0;
39 : uint32_t c;
40 :
41 94 : if (tok == NULL) return 0;
42 :
43 25 : c = type;
44 25 : memcpy(&buf[rp], &c, sizeof(uint32_t));
45 25 : rp += sizeof(uint32_t);
46 :
47 25 : c = size + sizeof(uint32_t);
48 25 : memcpy(&buf[rp], &c, sizeof(uint32_t));
49 25 : rp += sizeof(uint32_t);
50 :
51 25 : c = authtok_type;
52 25 : memcpy(&buf[rp], &c, sizeof(uint32_t));
53 25 : rp += sizeof(uint32_t);
54 :
55 25 : memcpy(&buf[rp], tok, size);
56 25 : rp += size;
57 :
58 25 : return rp;
59 : }
60 :
61 47 : static size_t add_uint32_t_item(enum pam_item_type type, const uint32_t val,
62 : uint8_t *buf)
63 : {
64 47 : size_t rp = 0;
65 : uint32_t c;
66 :
67 47 : c = type;
68 47 : memcpy(&buf[rp], &c, sizeof(uint32_t));
69 47 : rp += sizeof(uint32_t);
70 :
71 47 : c = sizeof(uint32_t);
72 47 : memcpy(&buf[rp], &c, sizeof(uint32_t));
73 47 : rp += sizeof(uint32_t);
74 :
75 47 : c = val;
76 47 : memcpy(&buf[rp], &c, sizeof(uint32_t));
77 47 : rp += sizeof(uint32_t);
78 :
79 47 : return rp;
80 : }
81 :
82 282 : static size_t add_string_item(enum pam_item_type type, const char *str,
83 : const size_t size, uint8_t *buf)
84 : {
85 282 : size_t rp = 0;
86 : uint32_t c;
87 :
88 282 : if (str == NULL || *str == '\0') return 0;
89 :
90 184 : c = type;
91 184 : memcpy(&buf[rp], &c, sizeof(uint32_t));
92 184 : rp += sizeof(uint32_t);
93 :
94 184 : c = size;
95 184 : memcpy(&buf[rp], &c, sizeof(uint32_t));
96 184 : rp += sizeof(uint32_t);
97 :
98 184 : memcpy(&buf[rp], str, size);
99 184 : rp += size;
100 :
101 184 : return rp;
102 : }
103 :
104 47 : int pack_message_v3(struct pam_items *pi, size_t *size, uint8_t **buffer)
105 : {
106 : int len;
107 : uint8_t *buf;
108 : size_t rp;
109 :
110 47 : len = sizeof(uint32_t) + sizeof(uint32_t);
111 :
112 90 : len += *pi->pam_user != '\0' ?
113 43 : 2*sizeof(uint32_t) + pi->pam_user_size : 0;
114 94 : len += *pi->pam_service != '\0' ?
115 47 : 2*sizeof(uint32_t) + pi->pam_service_size : 0;
116 78 : len += *pi->pam_tty != '\0' ?
117 31 : 2*sizeof(uint32_t) + pi->pam_tty_size : 0;
118 78 : len += *pi->pam_ruser != '\0' ?
119 31 : 2*sizeof(uint32_t) + pi->pam_ruser_size : 0;
120 78 : len += *pi->pam_rhost != '\0' ?
121 31 : 2*sizeof(uint32_t) + pi->pam_rhost_size : 0;
122 71 : len += pi->pam_authtok != NULL ?
123 24 : 3*sizeof(uint32_t) + pi->pam_authtok_size : 0;
124 48 : len += pi->pam_newauthtok != NULL ?
125 1 : 3*sizeof(uint32_t) + pi->pam_newauthtok_size : 0;
126 47 : len += 3*sizeof(uint32_t); /* cli_pid */
127 48 : len += *pi->requested_domains != '\0' ?
128 1 : 2*sizeof(uint32_t) + pi->requested_domains_size : 0;
129 :
130 47 : buf = malloc(len);
131 47 : if (buf == NULL) {
132 : D(("malloc failed."));
133 0 : return PAM_BUF_ERR;
134 : }
135 :
136 47 : rp = 0;
137 47 : SAFEALIGN_SETMEM_UINT32(buf, SSS_START_OF_PAM_REQUEST, &rp);
138 :
139 47 : rp += add_string_item(SSS_PAM_ITEM_USER, pi->pam_user, pi->pam_user_size,
140 : &buf[rp]);
141 :
142 47 : rp += add_string_item(SSS_PAM_ITEM_SERVICE, pi->pam_service,
143 : pi->pam_service_size, &buf[rp]);
144 :
145 47 : rp += add_string_item(SSS_PAM_ITEM_TTY, pi->pam_tty, pi->pam_tty_size,
146 : &buf[rp]);
147 :
148 47 : rp += add_string_item(SSS_PAM_ITEM_RUSER, pi->pam_ruser, pi->pam_ruser_size,
149 : &buf[rp]);
150 :
151 47 : rp += add_string_item(SSS_PAM_ITEM_RHOST, pi->pam_rhost, pi->pam_rhost_size,
152 : &buf[rp]);
153 :
154 47 : rp += add_string_item(SSS_PAM_ITEM_REQUESTED_DOMAINS, pi->requested_domains, pi->requested_domains_size,
155 : &buf[rp]);
156 :
157 47 : rp += add_uint32_t_item(SSS_PAM_ITEM_CLI_PID, (uint32_t) pi->cli_pid,
158 : &buf[rp]);
159 :
160 94 : rp += add_authtok_item(SSS_PAM_ITEM_AUTHTOK, pi->pam_authtok_type,
161 47 : pi->pam_authtok, pi->pam_authtok_size, &buf[rp]);
162 :
163 94 : rp += add_authtok_item(SSS_PAM_ITEM_NEWAUTHTOK, pi->pam_newauthtok_type,
164 47 : pi->pam_newauthtok, pi->pam_newauthtok_size,
165 : &buf[rp]);
166 :
167 47 : SAFEALIGN_SETMEM_UINT32(buf + rp, SSS_END_OF_PAM_REQUEST, &rp);
168 :
169 47 : if (rp != len) {
170 : D(("error during packet creation."));
171 0 : free(buf);
172 0 : return PAM_BUF_ERR;
173 : }
174 :
175 47 : *size = len;
176 47 : *buffer = buf;
177 :
178 47 : return 0;
179 : }
|