2006-08-04 03:46:20 +04:00
/*
* CIPSO - Commercial IP Security Option
*
* This is an implementation of the CIPSO 2.2 protocol as specified in
* draft - ietf - cipso - ipsecurity - 01. txt with additional tag types as found in
* FIPS - 188 , copies of both documents can be found in the Documentation
* directory . While CIPSO never became a full IETF RFC standard many vendors
* have chosen to adopt the protocol and over the years it has become a
* de - facto standard for labeled networking .
*
2011-08-01 15:10:33 +04:00
* Author : Paul Moore < paul @ paul - moore . com >
2006-08-04 03:46:20 +04:00
*
*/
/*
* ( c ) Copyright Hewlett - Packard Development Company , L . P . , 2006
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See
* the GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2013-12-06 21:13:40 +04:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2006-08-04 03:46:20 +04:00
*
*/
# ifndef _CIPSO_IPV4_H
# define _CIPSO_IPV4_H
# include <linux/types.h>
# include <linux/rcupdate.h>
# include <linux/list.h>
2006-08-30 04:56:04 +04:00
# include <linux/net.h>
# include <linux/skbuff.h>
2006-08-04 03:46:20 +04:00
# include <net/netlabel.h>
2009-03-28 00:10:34 +03:00
# include <net/request_sock.h>
2011-07-27 03:09:06 +04:00
# include <linux/atomic.h>
2012-06-01 09:54:56 +04:00
# include <asm/unaligned.h>
2006-08-04 03:46:20 +04:00
/* known doi values */
# define CIPSO_V4_DOI_UNKNOWN 0x00000000
2008-10-10 18:16:34 +04:00
/* standard tag types */
2006-08-04 03:46:20 +04:00
# define CIPSO_V4_TAG_INVALID 0
# define CIPSO_V4_TAG_RBITMAP 1
# define CIPSO_V4_TAG_ENUM 2
# define CIPSO_V4_TAG_RANGE 5
# define CIPSO_V4_TAG_PBITMAP 6
# define CIPSO_V4_TAG_FREEFORM 7
2008-10-10 18:16:34 +04:00
/* non-standard tag types (tags > 127) */
# define CIPSO_V4_TAG_LOCAL 128
2006-08-04 03:46:20 +04:00
/* doi mapping types */
# define CIPSO_V4_MAP_UNKNOWN 0
2008-10-10 18:16:34 +04:00
# define CIPSO_V4_MAP_TRANS 1
2006-08-04 03:46:20 +04:00
# define CIPSO_V4_MAP_PASS 2
2008-10-10 18:16:34 +04:00
# define CIPSO_V4_MAP_LOCAL 3
2006-08-04 03:46:20 +04:00
/* limits */
2006-11-18 01:38:51 +03:00
# define CIPSO_V4_MAX_REM_LVLS 255
2006-08-04 03:46:20 +04:00
# define CIPSO_V4_INV_LVL 0x80000000
# define CIPSO_V4_MAX_LOC_LVLS (CIPSO_V4_INV_LVL - 1)
2006-11-18 01:38:51 +03:00
# define CIPSO_V4_MAX_REM_CATS 65534
2006-08-04 03:46:20 +04:00
# define CIPSO_V4_INV_CAT 0x80000000
# define CIPSO_V4_MAX_LOC_CATS (CIPSO_V4_INV_CAT - 1)
/*
* CIPSO DOI definitions
*/
/* DOI definition struct */
# define CIPSO_V4_TAG_MAXCNT 5
struct cipso_v4_doi {
u32 doi ;
u32 type ;
union {
struct cipso_v4_std_map_tbl * std ;
} map ;
u8 tags [ CIPSO_V4_TAG_MAXCNT ] ;
2008-10-10 18:16:31 +04:00
atomic_t refcount ;
2006-08-04 03:46:20 +04:00
struct list_head list ;
struct rcu_head rcu ;
} ;
/* Standard CIPSO mapping table */
/* NOTE: the highest order bit (i.e. 0x80000000) is an 'invalid' flag, if the
* bit is set then consider that value as unspecified , meaning the
* mapping for that particular level / category is invalid */
struct cipso_v4_std_map_tbl {
struct {
u32 * cipso ;
u32 * local ;
u32 cipso_size ;
u32 local_size ;
} lvl ;
struct {
u32 * cipso ;
u32 * local ;
u32 cipso_size ;
u32 local_size ;
} cat ;
} ;
/*
* Sysctl Variables
*/
# ifdef CONFIG_NETLABEL
extern int cipso_v4_cache_enabled ;
extern int cipso_v4_cache_bucketsize ;
extern int cipso_v4_rbm_optfmt ;
extern int cipso_v4_rbm_strictvalid ;
# endif
/*
* DOI List Functions
*/
# ifdef CONFIG_NETLABEL
2008-12-31 20:54:11 +03:00
int cipso_v4_doi_add ( struct cipso_v4_doi * doi_def ,
struct netlbl_audit * audit_info ) ;
2008-10-10 18:16:31 +04:00
void cipso_v4_doi_free ( struct cipso_v4_doi * doi_def ) ;
int cipso_v4_doi_remove ( u32 doi , struct netlbl_audit * audit_info ) ;
2006-08-04 03:46:20 +04:00
struct cipso_v4_doi * cipso_v4_doi_getdef ( u32 doi ) ;
2008-10-10 18:16:31 +04:00
void cipso_v4_doi_putdef ( struct cipso_v4_doi * doi_def ) ;
2006-09-26 02:56:09 +04:00
int cipso_v4_doi_walk ( u32 * skip_cnt ,
int ( * callback ) ( struct cipso_v4_doi * doi_def , void * arg ) ,
void * cb_arg ) ;
2006-08-04 03:46:20 +04:00
# else
2008-12-31 20:54:11 +03:00
static inline int cipso_v4_doi_add ( struct cipso_v4_doi * doi_def ,
struct netlbl_audit * audit_info )
2006-08-04 03:46:20 +04:00
{
return - ENOSYS ;
}
2008-10-10 18:16:31 +04:00
static inline void cipso_v4_doi_free ( struct cipso_v4_doi * doi_def )
{
return ;
}
2006-08-04 03:46:20 +04:00
static inline int cipso_v4_doi_remove ( u32 doi ,
2008-10-10 18:16:31 +04:00
struct netlbl_audit * audit_info )
2006-08-04 03:46:20 +04:00
{
return 0 ;
}
static inline struct cipso_v4_doi * cipso_v4_doi_getdef ( u32 doi )
{
return NULL ;
}
2006-09-26 02:56:09 +04:00
static inline int cipso_v4_doi_walk ( u32 * skip_cnt ,
int ( * callback ) ( struct cipso_v4_doi * doi_def , void * arg ) ,
void * cb_arg )
2006-08-04 03:46:20 +04:00
{
2006-09-26 02:56:09 +04:00
return 0 ;
2006-08-04 03:46:20 +04:00
}
static inline int cipso_v4_doi_domhsh_add ( struct cipso_v4_doi * doi_def ,
const char * domain )
{
return - ENOSYS ;
}
static inline int cipso_v4_doi_domhsh_remove ( struct cipso_v4_doi * doi_def ,
const char * domain )
{
return 0 ;
}
# endif /* CONFIG_NETLABEL */
/*
* Label Mapping Cache Functions
*/
# ifdef CONFIG_NETLABEL
void cipso_v4_cache_invalidate ( void ) ;
2015-02-11 22:46:37 +03:00
int cipso_v4_cache_add ( const unsigned char * cipso_ptr ,
2006-08-04 03:46:20 +04:00
const struct netlbl_lsm_secattr * secattr ) ;
# else
static inline void cipso_v4_cache_invalidate ( void )
{
return ;
}
2015-02-11 22:46:37 +03:00
static inline int cipso_v4_cache_add ( const unsigned char * cipso_ptr ,
2006-08-04 03:46:20 +04:00
const struct netlbl_lsm_secattr * secattr )
{
return 0 ;
}
# endif /* CONFIG_NETLABEL */
/*
* Protocol Handling Functions
*/
# ifdef CONFIG_NETLABEL
void cipso_v4_error ( struct sk_buff * skb , int error , u32 gateway ) ;
2015-02-11 22:46:37 +03:00
int cipso_v4_getattr ( const unsigned char * cipso ,
struct netlbl_lsm_secattr * secattr ) ;
2007-06-08 05:37:15 +04:00
int cipso_v4_sock_setattr ( struct sock * sk ,
const struct cipso_v4_doi * doi_def ,
const struct netlbl_lsm_secattr * secattr ) ;
2008-10-10 18:16:33 +04:00
void cipso_v4_sock_delattr ( struct sock * sk ) ;
2006-09-26 02:52:01 +04:00
int cipso_v4_sock_getattr ( struct sock * sk , struct netlbl_lsm_secattr * secattr ) ;
2009-03-28 00:10:34 +03:00
int cipso_v4_req_setattr ( struct request_sock * req ,
const struct cipso_v4_doi * doi_def ,
const struct netlbl_lsm_secattr * secattr ) ;
void cipso_v4_req_delattr ( struct request_sock * req ) ;
2008-10-10 18:16:32 +04:00
int cipso_v4_skbuff_setattr ( struct sk_buff * skb ,
const struct cipso_v4_doi * doi_def ,
const struct netlbl_lsm_secattr * secattr ) ;
int cipso_v4_skbuff_delattr ( struct sk_buff * skb ) ;
2006-08-04 03:46:20 +04:00
int cipso_v4_skbuff_getattr ( const struct sk_buff * skb ,
struct netlbl_lsm_secattr * secattr ) ;
2015-02-11 22:46:37 +03:00
unsigned char * cipso_v4_optptr ( const struct sk_buff * skb ) ;
2008-10-10 18:16:34 +04:00
int cipso_v4_validate ( const struct sk_buff * skb , unsigned char * * option ) ;
2006-08-04 03:46:20 +04:00
# else
static inline void cipso_v4_error ( struct sk_buff * skb ,
int error ,
u32 gateway )
{
return ;
}
2015-02-11 22:46:37 +03:00
static inline int cipso_v4_getattr ( const unsigned char * cipso ,
struct netlbl_lsm_secattr * secattr )
{
return - ENOSYS ;
}
2007-06-08 05:37:15 +04:00
static inline int cipso_v4_sock_setattr ( struct sock * sk ,
const struct cipso_v4_doi * doi_def ,
const struct netlbl_lsm_secattr * secattr )
2006-08-04 03:46:20 +04:00
{
return - ENOSYS ;
}
2008-10-10 18:16:33 +04:00
static inline void cipso_v4_sock_delattr ( struct sock * sk )
{
}
2006-09-26 02:52:01 +04:00
static inline int cipso_v4_sock_getattr ( struct sock * sk ,
struct netlbl_lsm_secattr * secattr )
{
return - ENOSYS ;
}
2009-03-28 00:10:34 +03:00
static inline int cipso_v4_req_setattr ( struct request_sock * req ,
const struct cipso_v4_doi * doi_def ,
const struct netlbl_lsm_secattr * secattr )
{
return - ENOSYS ;
}
static inline void cipso_v4_req_delattr ( struct request_sock * req )
{
return ;
}
2008-10-10 18:16:32 +04:00
static inline int cipso_v4_skbuff_setattr ( struct sk_buff * skb ,
const struct cipso_v4_doi * doi_def ,
const struct netlbl_lsm_secattr * secattr )
{
return - ENOSYS ;
}
static inline int cipso_v4_skbuff_delattr ( struct sk_buff * skb )
{
return - ENOSYS ;
}
2006-08-04 03:46:20 +04:00
static inline int cipso_v4_skbuff_getattr ( const struct sk_buff * skb ,
struct netlbl_lsm_secattr * secattr )
{
return - ENOSYS ;
}
2015-02-11 22:46:37 +03:00
static inline unsigned char * cipso_v4_optptr ( const struct sk_buff * skb )
{
return NULL ;
}
2008-10-10 18:16:34 +04:00
static inline int cipso_v4_validate ( const struct sk_buff * skb ,
unsigned char * * option )
2006-08-04 03:46:20 +04:00
{
2012-06-01 09:54:56 +04:00
unsigned char * opt = * option ;
unsigned char err_offset = 0 ;
u8 opt_len = opt [ 1 ] ;
u8 opt_iter ;
2013-10-18 07:33:21 +04:00
u8 tag_len ;
2012-06-01 09:54:56 +04:00
if ( opt_len < 8 ) {
err_offset = 1 ;
goto out ;
}
if ( get_unaligned_be32 ( & opt [ 2 ] ) = = 0 ) {
err_offset = 2 ;
goto out ;
}
for ( opt_iter = 6 ; opt_iter < opt_len ; ) {
2013-10-18 07:33:21 +04:00
tag_len = opt [ opt_iter + 1 ] ;
2013-12-11 00:00:50 +04:00
if ( ( tag_len = = 0 ) | | ( tag_len > ( opt_len - opt_iter ) ) ) {
2012-06-01 09:54:56 +04:00
err_offset = opt_iter + 1 ;
goto out ;
}
2013-10-18 07:33:21 +04:00
opt_iter + = tag_len ;
2012-06-01 09:54:56 +04:00
}
out :
* option = opt + err_offset ;
return err_offset ;
2006-08-04 03:46:20 +04:00
}
# endif /* CONFIG_NETLABEL */
# endif /* _CIPSO_IPV4_H */