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 80 : 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 80 : size_t rp = 0;
39 : uint32_t c;
40 :
41 80 : if (tok == NULL) return 0;
42 :
43 22 : c = type;
44 22 : memcpy(&buf[rp], &c, sizeof(uint32_t));
45 22 : rp += sizeof(uint32_t);
46 :
47 22 : c = size + sizeof(uint32_t);
48 22 : memcpy(&buf[rp], &c, sizeof(uint32_t));
49 22 : rp += sizeof(uint32_t);
50 :
51 22 : c = authtok_type;
52 22 : memcpy(&buf[rp], &c, sizeof(uint32_t));
53 22 : rp += sizeof(uint32_t);
54 :
55 22 : memcpy(&buf[rp], tok, size);
56 22 : rp += size;
57 :
58 22 : return rp;
59 : }
60 :
61 40 : static size_t add_uint32_t_item(enum pam_item_type type, const uint32_t val,
62 : uint8_t *buf)
63 : {
64 40 : size_t rp = 0;
65 : uint32_t c;
66 :
67 40 : c = type;
68 40 : memcpy(&buf[rp], &c, sizeof(uint32_t));
69 40 : rp += sizeof(uint32_t);
70 :
71 40 : c = sizeof(uint32_t);
72 40 : memcpy(&buf[rp], &c, sizeof(uint32_t));
73 40 : rp += sizeof(uint32_t);
74 :
75 40 : c = val;
76 40 : memcpy(&buf[rp], &c, sizeof(uint32_t));
77 40 : rp += sizeof(uint32_t);
78 :
79 40 : return rp;
80 : }
81 :
82 240 : static size_t add_string_item(enum pam_item_type type, const char *str,
83 : const size_t size, uint8_t *buf)
84 : {
85 240 : size_t rp = 0;
86 : uint32_t c;
87 :
88 240 : if (str == NULL || *str == '\0') return 0;
89 :
90 196 : c = type;
91 196 : memcpy(&buf[rp], &c, sizeof(uint32_t));
92 196 : rp += sizeof(uint32_t);
93 :
94 196 : c = size;
95 196 : memcpy(&buf[rp], &c, sizeof(uint32_t));
96 196 : rp += sizeof(uint32_t);
97 :
98 196 : memcpy(&buf[rp], str, size);
99 196 : rp += size;
100 :
101 196 : return rp;
102 : }
103 :
104 40 : 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 40 : len = sizeof(uint32_t) + sizeof(uint32_t);
111 :
112 76 : len += *pi->pam_user != '\0' ?
113 36 : 2*sizeof(uint32_t) + pi->pam_user_size : 0;
114 80 : len += *pi->pam_service != '\0' ?
115 40 : 2*sizeof(uint32_t) + pi->pam_service_size : 0;
116 80 : len += *pi->pam_tty != '\0' ?
117 40 : 2*sizeof(uint32_t) + pi->pam_tty_size : 0;
118 80 : len += *pi->pam_ruser != '\0' ?
119 40 : 2*sizeof(uint32_t) + pi->pam_ruser_size : 0;
120 80 : len += *pi->pam_rhost != '\0' ?
121 40 : 2*sizeof(uint32_t) + pi->pam_rhost_size : 0;
122 62 : len += pi->pam_authtok != NULL ?
123 22 : 3*sizeof(uint32_t) + pi->pam_authtok_size : 0;
124 40 : len += pi->pam_newauthtok != NULL ?
125 0 : 3*sizeof(uint32_t) + pi->pam_newauthtok_size : 0;
126 40 : len += 3*sizeof(uint32_t); /* cli_pid */
127 40 : len += *pi->requested_domains != '\0' ?
128 0 : 2*sizeof(uint32_t) + pi->requested_domains_size : 0;
129 :
130 40 : buf = malloc(len);
131 40 : if (buf == NULL) {
132 : D(("malloc failed."));
133 0 : return PAM_BUF_ERR;
134 : }
135 :
136 40 : rp = 0;
137 40 : SAFEALIGN_SETMEM_UINT32(buf, SSS_START_OF_PAM_REQUEST, &rp);
138 :
139 40 : rp += add_string_item(SSS_PAM_ITEM_USER, pi->pam_user, pi->pam_user_size,
140 : &buf[rp]);
141 :
142 40 : rp += add_string_item(SSS_PAM_ITEM_SERVICE, pi->pam_service,
143 : pi->pam_service_size, &buf[rp]);
144 :
145 40 : rp += add_string_item(SSS_PAM_ITEM_TTY, pi->pam_tty, pi->pam_tty_size,
146 : &buf[rp]);
147 :
148 40 : rp += add_string_item(SSS_PAM_ITEM_RUSER, pi->pam_ruser, pi->pam_ruser_size,
149 : &buf[rp]);
150 :
151 40 : rp += add_string_item(SSS_PAM_ITEM_RHOST, pi->pam_rhost, pi->pam_rhost_size,
152 : &buf[rp]);
153 :
154 40 : rp += add_string_item(SSS_PAM_ITEM_REQUESTED_DOMAINS, pi->requested_domains, pi->requested_domains_size,
155 : &buf[rp]);
156 :
157 40 : rp += add_uint32_t_item(SSS_PAM_ITEM_CLI_PID, (uint32_t) pi->cli_pid,
158 : &buf[rp]);
159 :
160 80 : rp += add_authtok_item(SSS_PAM_ITEM_AUTHTOK, pi->pam_authtok_type,
161 40 : pi->pam_authtok, pi->pam_authtok_size, &buf[rp]);
162 :
163 80 : rp += add_authtok_item(SSS_PAM_ITEM_NEWAUTHTOK, pi->pam_newauthtok_type,
164 40 : pi->pam_newauthtok, pi->pam_newauthtok_size,
165 : &buf[rp]);
166 :
167 40 : SAFEALIGN_SETMEM_UINT32(buf + rp, SSS_END_OF_PAM_REQUEST, &rp);
168 :
169 40 : if (rp != len) {
170 : D(("error during packet creation."));
171 0 : free(buf);
172 0 : return PAM_BUF_ERR;
173 : }
174 :
175 40 : *size = len;
176 40 : *buffer = buf;
177 :
178 40 : return 0;
179 : }
|