1 /* cvm/module_request.c - Request parsing code
2 * Copyright (C) 2010 Bruce Guenter <bruce@untroubled.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 #include <stdlib.h>
19 #include <string.h>
20 #include "module.h"
21 #include "protocol.h"
22
23 const char* cvm_account_name;
24 const char* cvm_account_domain;
25
26 unsigned char cvm_module_inbuffer[BUFSIZE+1];
27 unsigned cvm_module_inbuflen;
28
29 const char* cvm_module_lookup_secret = 0;
30
31 str cvm_module_credentials[CVM_CRED_MAX+1];
32
cvm_module_init_request(void)33 void cvm_module_init_request(void)
34 {
35 /* Determine if the module is to operate in lookup mode, and if not
36 set the local credential values appropriately. */
37 cvm_module_lookup_secret = getenv("CVM_LOOKUP_SECRET");
38 memset(cvm_module_credentials, 0, sizeof cvm_module_credentials);
39 }
40
v1copy_advance(const char ** ptr,char ** buf,unsigned * len)41 static int v1copy_advance(const char** ptr, char** buf, unsigned* len)
42 {
43 char* tmp;
44 if ((tmp = memchr(*buf, 0, *len)) == 0) return 0;
45 ++tmp;
46 if (*len < (unsigned)(tmp - *buf)) return 0;
47 *ptr = *buf;
48 *len -= tmp - *buf;
49 *buf = tmp;
50 return 1;
51 }
52
parse_v1_input(void)53 static int parse_v1_input(void)
54 {
55 char* buf;
56 unsigned len;
57 const char* cred;
58
59 /* Prevent buffer run-off by ensuring there is at least one NUL byte */
60 cvm_module_inbuffer[BUFSIZE] = 0;
61 buf = (char*)cvm_module_inbuffer + 1;
62 len = cvm_module_inbuflen - 1;
63
64 /* Account name */
65 if (!v1copy_advance(&cred, &buf, &len)) return CVME_BAD_CLIDATA;
66 if (!str_copys(&cvm_module_credentials[CVM_CRED_ACCOUNT], cred))
67 return CVME_IO;
68
69 /* Domain name */
70 if (!v1copy_advance(&cred, &buf, &len)) return CVME_BAD_CLIDATA;
71 if (*cred != 0
72 && !str_copys(&cvm_module_credentials[CVM_CRED_DOMAIN], cred))
73 return CVME_IO;
74
75 if (len > 1) {
76 /* Allow for only a single credential if one is present.
77 No existing CVM1 module could handle more than one. */
78 if (!v1copy_advance(&cred, &buf, &len))
79 return CVME_BAD_CLIDATA;
80 if (!str_copys((cvm_module_lookup_secret != 0)
81 ? &cvm_module_credentials[CVM_CRED_SECRET]
82 : &cvm_module_credentials[CVM_CRED_PASSWORD], cred))
83 return CVME_IO;
84 }
85
86 if (len != 1) return CVME_BAD_CLIDATA;
87 return 0;
88 }
89
parse_v2_input(void)90 static int parse_v2_input(void)
91 {
92 unsigned i;
93 unsigned len;
94 unsigned type;
95 for (i = cvm_module_inbuffer[1] + 2;
96 i < cvm_module_inbuflen - 2;
97 i += len + 2) {
98 type = cvm_module_inbuffer[i];
99 len = cvm_module_inbuffer[i+1];
100 if (type <= CVM_CRED_MAX)
101 if (!str_copyb(&cvm_module_credentials[type],
102 (char*)cvm_module_inbuffer+i+2, len))
103 return CVME_IO;
104 }
105 if (i >= cvm_module_inbuflen
106 || cvm_module_inbuffer[i] != 0)
107 return CVME_BAD_CLIDATA;
108 return 0;
109 }
110
parse_input(void)111 static int parse_input(void)
112 {
113 if (cvm_module_inbuffer[0] == CVM2_PROTOCOL)
114 return parse_v2_input();
115 if (cvm_module_inbuffer[0] == CVM1_PROTOCOL)
116 return parse_v1_input();
117 return CVME_BAD_CLIDATA;
118 }
119
cvm_module_handle_request(void)120 int cvm_module_handle_request(void)
121 {
122 int code;
123 unsigned i;
124 for (i = 0; i <= CVM_CRED_MAX; ++i)
125 cvm_module_credentials[i].len = 0;
126 cvm_module_fact_start();
127 if ((code = parse_input()) != 0) return code;
128 if (cvm_module_lookup_secret != 0 && *cvm_module_lookup_secret != 0) {
129 if (cvm_module_credentials[CVM_CRED_SECRET].len == 0
130 || str_diffs(&cvm_module_credentials[CVM_CRED_SECRET],
131 cvm_module_lookup_secret) != 0)
132 return CVME_NOCRED;
133 }
134 if ((code = cvm_module_lookup()) != 0) return code;
135 if (cvm_module_lookup_secret == 0)
136 if ((code = cvm_module_authenticate()) != 0) return code;
137 if ((code = cvm_module_results()) != 0) return code;
138 cvm_module_fact_str(CVM_FACT_USERNAME, cvm_fact_username);
139 cvm_module_fact_uint(CVM_FACT_USERID, cvm_fact_userid);
140 cvm_module_fact_uint(CVM_FACT_GROUPID, cvm_fact_groupid);
141 if (cvm_fact_realname)
142 cvm_module_fact_str(CVM_FACT_REALNAME, cvm_fact_realname);
143 cvm_module_fact_str(CVM_FACT_DIRECTORY, cvm_fact_directory);
144 if (cvm_fact_shell)
145 cvm_module_fact_str(CVM_FACT_SHELL, cvm_fact_shell);
146 if (cvm_fact_groupname)
147 cvm_module_fact_str(CVM_FACT_GROUPNAME, cvm_fact_groupname);
148 if (cvm_fact_sys_username)
149 cvm_module_fact_str(CVM_FACT_SYS_USERNAME, cvm_fact_sys_username);
150 if (cvm_fact_sys_directory)
151 cvm_module_fact_str(CVM_FACT_SYS_DIRECTORY, cvm_fact_sys_directory);
152 if (cvm_fact_domain)
153 cvm_module_fact_str(CVM_FACT_DOMAIN, cvm_fact_domain);
154 if (cvm_fact_mailbox)
155 cvm_module_fact_str(CVM_FACT_MAILBOX, cvm_fact_mailbox);
156 return 0;
157 }
158