1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2012 The FreeBSD Foundation 5 * 6 * This software was developed by Edward Tomasz Napierala under sponsorship 7 * from the FreeBSD Foundation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #ifndef __LIBISCSIUTIL_H__ 32 #define __LIBISCSIUTIL_H__ 33 34 #include <sys/types.h> 35 #include <stdbool.h> 36 37 struct connection_ops; 38 39 #define CONN_DIGEST_NONE 0 40 #define CONN_DIGEST_CRC32C 1 41 42 struct connection { 43 const struct connection_ops *conn_ops; 44 int conn_socket; 45 uint8_t conn_isid[6]; 46 uint16_t conn_tsih; 47 uint32_t conn_cmdsn; 48 uint32_t conn_statsn; 49 int conn_header_digest; 50 int conn_data_digest; 51 bool conn_immediate_data; 52 bool conn_use_proxy; 53 int conn_max_recv_data_segment_length; 54 int conn_max_send_data_segment_length; 55 int conn_max_burst_length; 56 int conn_first_burst_length; 57 }; 58 59 struct pdu { 60 struct connection *pdu_connection; 61 struct iscsi_bhs *pdu_bhs; 62 char *pdu_data; 63 size_t pdu_data_len; 64 }; 65 66 struct connection_ops { 67 bool (*timed_out)(void); 68 void (*pdu_receive_proxy)(struct pdu *); 69 void (*pdu_send_proxy)(struct pdu *); 70 void (*fail)(const struct connection *, const char *); 71 }; 72 73 #define KEYS_MAX 1024 74 75 struct keys { 76 char *keys_names[KEYS_MAX]; 77 char *keys_values[KEYS_MAX]; 78 }; 79 80 #define CHAP_CHALLENGE_LEN 1024 81 #define CHAP_DIGEST_LEN 16 /* Equal to MD5 digest size. */ 82 83 struct chap { 84 unsigned char chap_id; 85 char chap_challenge[CHAP_CHALLENGE_LEN]; 86 char chap_response[CHAP_DIGEST_LEN]; 87 }; 88 89 struct rchap { 90 char *rchap_secret; 91 unsigned char rchap_id; 92 void *rchap_challenge; 93 size_t rchap_challenge_len; 94 }; 95 96 struct chap *chap_new(void); 97 char *chap_get_id(const struct chap *chap); 98 char *chap_get_challenge(const struct chap *chap); 99 int chap_receive(struct chap *chap, const char *response); 100 int chap_authenticate(struct chap *chap, 101 const char *secret); 102 void chap_delete(struct chap *chap); 103 104 struct rchap *rchap_new(const char *secret); 105 int rchap_receive(struct rchap *rchap, 106 const char *id, const char *challenge); 107 char *rchap_get_response(struct rchap *rchap); 108 void rchap_delete(struct rchap *rchap); 109 110 struct keys *keys_new(void); 111 void keys_delete(struct keys *key); 112 void keys_load(struct keys *keys, const char *data, 113 size_t len); 114 void keys_save(struct keys *keys, char **datap, 115 size_t *lenp); 116 const char *keys_find(struct keys *keys, const char *name); 117 void keys_add(struct keys *keys, 118 const char *name, const char *value); 119 void keys_add_int(struct keys *keys, 120 const char *name, int value); 121 122 static __inline void 123 keys_load_pdu(struct keys *keys, const struct pdu *pdu) 124 { 125 keys_load(keys, pdu->pdu_data, pdu->pdu_data_len); 126 } 127 128 static __inline void 129 keys_save_pdu(struct keys *keys, struct pdu *pdu) 130 { 131 keys_save(keys, &pdu->pdu_data, &pdu->pdu_data_len); 132 } 133 134 struct pdu *pdu_new(struct connection *ic); 135 struct pdu *pdu_new_response(struct pdu *request); 136 int pdu_ahs_length(const struct pdu *pdu); 137 int pdu_data_segment_length(const struct pdu *pdu); 138 void pdu_set_data_segment_length(struct pdu *pdu, 139 uint32_t len); 140 void pdu_receive(struct pdu *request); 141 void pdu_send(struct pdu *response); 142 void pdu_delete(struct pdu *ip); 143 144 void text_send_request(struct connection *conn, 145 struct keys *request_keys); 146 struct keys * text_read_response(struct connection *conn); 147 struct keys * text_read_request(struct connection *conn, 148 struct pdu **requestp); 149 void text_send_response(struct pdu *request, 150 struct keys *response_keys); 151 152 void connection_init(struct connection *conn, 153 const struct connection_ops *ops, bool use_proxy); 154 155 void log_init(int level); 156 void log_set_peer_name(const char *name); 157 void log_set_peer_addr(const char *addr); 158 void log_err(int, const char *, ...) 159 __dead2 __printflike(2, 3); 160 void log_errx(int, const char *, ...) 161 __dead2 __printflike(2, 3); 162 void log_warn(const char *, ...) __printflike(1, 2); 163 void log_warnx(const char *, ...) __printflike(1, 2); 164 void log_debugx(const char *, ...) __printflike(1, 2); 165 166 char *checked_strdup(const char *); 167 168 #endif /* !__LIBISCSIUTIL_H__ */ 169