1 /*	$OpenBSD: intercept.h,v 1.24 2006/07/02 12:34:15 sturm Exp $	*/
2 /*
3  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. All advertising materials mentioning features or use of this software
15  *    must display the following acknowledgement:
16  *      This product includes software developed by Niels Provos.
17  * 4. The name of the author may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #ifndef _INTERCEPT_H_
33 #define _INTERCEPT_H_
34 #include <sys/param.h>
35 #include <sys/queue.h>
36 
37 struct intercept_pid;
38 struct intercept_replace;
39 struct elevate;
40 
41 struct intercept_system {
42 	char *name;
43 	int (*init)(void);
44 	int (*open)(void);
45 	int (*attach)(int, pid_t);
46 	int (*detach)(int, pid_t);
47 	int (*report)(int, pid_t);
48 	int (*read)(int);
49 	int (*getsyscallnumber)(const char *, const char *);
50 	int (*setcwd)(int, pid_t);
51 	int (*restcwd)(int);
52 	int (*io)(int, pid_t, int, void *, u_char *, size_t);
53 	int (*getarg)(int, void *, int, void **);
54 	int (*answer)(int, pid_t, u_int16_t, short, int, short,
55 	    struct elevate *);
56 	int (*newpolicy)(int);
57 	int (*assignpolicy)(int, pid_t, int);
58 	int (*policy)(int, int, int, short);
59 	int (*replace)(int, pid_t, u_int16_t, struct intercept_replace *);
60 	void (*clonepid)(struct intercept_pid *, struct intercept_pid *);
61 	void (*freepid)(struct intercept_pid *);
62 	int (*scriptname)(int, pid_t, char *);
63 };
64 
65 #define INTERCEPT_READ	1
66 #define INTERCEPT_WRITE	2
67 
68 #define ICPOLICY_ASK	0
69 #define ICPOLICY_PERMIT	-1
70 #define ICPOLICY_KILL	-2
71 #define ICPOLICY_NEVER	1	/* overloaded with errno values > 1 */
72 
73 #define ICLINK_NONE	0	/* do not resolve symlinks */
74 #define ICLINK_ALL	1	/* resolve all symlinks */
75 #define ICLINK_NOLAST	2	/* do not resolve last component */
76 
77 #define ICFLAGS_RESULT	1
78 
79 #define	ICTRANS_NOLINKS	1	/* translation should have no symlinks */
80 
81 /* Privilege elevation */
82 struct elevate {
83 #define ELEVATE_UID	0x01
84 #define ELEVATE_GID	0x02
85 	int e_flags;
86 	uid_t e_uid;
87 	gid_t e_gid;
88 };
89 
90 struct intercept_pid {
91 	SPLAY_ENTRY(intercept_pid) next;
92 	pid_t pid;
93 	pid_t ppid;		/* parent pid */
94 
95 	int policynr;
96 	int execve_code;
97 	short execve_policy;
98 	char *name;		/* name of current process image */
99 	char *newname;		/* image name to be committed by execve */
100 
101 	uid_t uid;		/* current uid */
102 	gid_t gid;		/* current gid */
103 
104 #ifndef LOGIN_NAME_MAX
105 #define LOGIN_NAME_MAX	MAXLOGNAME
106 #endif
107 	char username[LOGIN_NAME_MAX];
108 	char home[MAXPATHLEN];	/* current home dir for uid */
109 
110 	void *data;
111 
112 	int uflags;	/* Flags that can be used by external application */
113 	struct elevate *elevate;	/* privilege elevation request */
114 };
115 
116 #define INTERCEPT_MAXSYSCALLNR		512
117 #define INTERCEPT_MAXSYSCALLARGS	10
118 
119 struct intercept_translate {
120 	char *name;
121 	int (*translate)(struct intercept_translate *, int, pid_t, void *);
122 	int (*print)(char *, size_t, struct intercept_translate *);
123 	int off2;
124 	int off;
125 	u_char trans_valid;
126 	void *trans_addr;
127 	void *trans_addr2;
128 	void *trans_data;
129 	size_t trans_size;
130 	char *trans_print;
131 	u_int trans_flags;
132 	void *user;
133 	TAILQ_ENTRY(intercept_translate) next;
134 };
135 
136 struct intercept_replace {
137 	int num;
138 	int ind[INTERCEPT_MAXSYSCALLARGS];
139 	u_char *address[INTERCEPT_MAXSYSCALLARGS];
140 	size_t len[INTERCEPT_MAXSYSCALLARGS];
141 	u_int flags[INTERCEPT_MAXSYSCALLARGS];
142 };
143 
144 TAILQ_HEAD(intercept_tlq, intercept_translate);
145 
146 int intercept_init(void);
147 pid_t intercept_run(int, int, uid_t, gid_t, char *, char * const *);
148 int intercept_open(void);
149 int intercept_attach(int, pid_t);
150 int intercept_attachpid(int, pid_t, char *);
151 int intercept_detach(int, pid_t);
152 int intercept_read(int);
153 int intercept_newpolicy(int);
154 int intercept_assignpolicy(int, pid_t, int);
155 int intercept_modifypolicy(int, int, const char *, const char *, short);
156 int intercept_modifypolicy_nr(int, int, int, short);
157 void intercept_child_info(pid_t, pid_t);
158 void intercept_policy_free(int);
159 
160 int intercept_replace_init(struct intercept_replace *);
161 int intercept_replace_add(struct intercept_replace *, int, u_char *, size_t, u_int);
162 int intercept_replace(int, pid_t, u_int16_t, struct intercept_replace *);
163 
164 int intercept_register_sccb(char *, char *,
165     short (*)(int, pid_t, int, const char *, int, const char *, void *, int,
166 	struct intercept_replace *, struct intercept_tlq *, void *),
167     void *);
168 void *intercept_sccb_cbarg(char *, char *);
169 
170 int intercept_register_gencb(short (*)(int, pid_t, int, const char *, int, const char *, void *, int, void *), void *);
171 int intercept_register_execcb(void (*)(int, pid_t, int, const char *, const char *, void *), void *);
172 int intercept_register_pfreecb(void (*)(int, void *), void *);
173 
174 struct intercept_translate *intercept_register_translation(char *, char *,
175     int, struct intercept_translate *);
176 int intercept_translate(struct intercept_translate *, int, pid_t, int, void *, int);
177 char *intercept_translate_print(struct intercept_translate *);
178 
179 #define intercept_register_transstring(x,y,z)	\
180 	intercept_register_translation(x, y, z, &ic_translate_string)
181 #define intercept_register_transfn(x,y,z)	\
182 	intercept_register_translation(x, y, z, &ic_translate_filename)
183 #define intercept_register_translink(x,y,z)	\
184 	intercept_register_translation(x, y, z, &ic_translate_linkname)
185 
186 extern struct intercept_translate ic_translate_string;
187 extern struct intercept_translate ic_translate_filename;
188 extern struct intercept_translate ic_translate_linkname;
189 extern struct intercept_translate ic_translate_unlinkname;
190 extern struct intercept_translate ic_translate_connect;
191 extern struct intercept_translate ic_translate_sendmsg;
192 
193 void intercept_freepid(pid_t);
194 struct intercept_pid *intercept_findpid(pid_t);
195 struct intercept_pid *intercept_getpid(pid_t);
196 int intercept_existpids(void);
197 
198 char *intercept_get_string(int, pid_t, void *);
199 char *normalize_filename(int, pid_t, char *, int);
200 char *intercept_filename(int, pid_t, void *, int, char *);
201 void intercept_syscall(int, pid_t, u_int16_t, int, const char *, int,
202     const char *, void *, int);
203 void intercept_syscall_result(int, pid_t, u_int16_t, int, const char *, int,
204     const char *, void *, int, int, void *);
205 void intercept_newimage(int, pid_t, int,
206     const char *, char *, struct intercept_pid *);
207 void intercept_ugid(struct intercept_pid *, uid_t, gid_t);
208 void intercept_setpid(struct intercept_pid *, uid_t, gid_t);
209 
210 int intercept_getsyscallnumber(const char *, const char *);
211 int intercept_isvalidsystemcall(const char *, const char *);
212 
213 #endif /* _INTERCEPT_H_ */
214