URL encoded Targetnames

Assume target names are URL encoded with '%' as the special character.

Any sequence of '%' followed by two bytes in the target name will be replaced
with the byte that the second two bytes represent in hexadecimal.

Example
iqn.ronnie.test%3A1234
will be translated to iqn.ronnie.test:1234
This commit is contained in:
Ronnie Sahlberg
2013-06-16 11:35:14 -07:00
parent 12f93b60c7
commit e061cba1b9
3 changed files with 88 additions and 39 deletions

View File

@@ -84,10 +84,10 @@ EXTERN int iscsi_set_timeout(struct iscsi_context *iscsi, int timeout);
EXTERN int iscsi_set_tcp_keepalive(struct iscsi_context *iscsi, int idle, int count, int interval); EXTERN int iscsi_set_tcp_keepalive(struct iscsi_context *iscsi, int idle, int count, int interval);
struct iscsi_url { struct iscsi_url {
char portal[MAX_STRING_SIZE+1]; char portal[MAX_STRING_SIZE + 1];
char target[MAX_STRING_SIZE+1]; char target[MAX_STRING_SIZE + 1];
char user[MAX_STRING_SIZE+1]; char user[MAX_STRING_SIZE + 1];
char passwd[MAX_STRING_SIZE+1]; char passwd[MAX_STRING_SIZE + 1];
int lun; int lun;
struct iscsi_context *iscsi; struct iscsi_context *iscsi;
}; };
@@ -125,6 +125,10 @@ iscsi_set_initial_r2t(struct iscsi_context *iscsi, enum iscsi_initial_r2t initia
* iSCSI URL format : * iSCSI URL format :
* iscsi://[<username>[%<password>]@]<host>[:<port>]/<target-iqn>/<lun> * iscsi://[<username>[%<password>]@]<host>[:<port>]/<target-iqn>/<lun>
* *
* Target names are url encoded with '%' as a special character.
* Example:
* "iqn.ronnie.test%3A1234" will be translated to "iqn.ronnie.test:1234"
*
* Function will return a pointer to an iscsi url structure if successful, * Function will return a pointer to an iscsi url structure if successful,
* or it will return NULL and set iscsi_get_error() accrodingly if there was a problem * or it will return NULL and set iscsi_get_error() accrodingly if there was a problem
* with the URL. * with the URL.

View File

@@ -358,6 +358,45 @@ iscsi_is_logged_in(struct iscsi_context *iscsi)
return iscsi->is_loggedin; return iscsi->is_loggedin;
} }
static int
h2i(int h)
{
if (h >= 'a' && h <= 'f') {
return h - 'a' + 10;
}
if (h >= 'A' && h <= 'F') {
return h - 'A' + 10;
}
return h - '0';
}
static void
iscsi_decode_url_string(char *str)
{
while (*str) {
char *tmp = str;
char c;
if (*str++ != '%') {
continue;
}
if (*str == 0) {
return;
}
c = h2i(*str++) << 4;
if (*str == 0) {
return;
}
c |= h2i(*str++);
*tmp++ = c;
memmove(tmp, str, strlen(str));
tmp[strlen(str)] = 0;
}
}
struct iscsi_url * struct iscsi_url *
iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full) iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full)
{ {
@@ -373,15 +412,18 @@ iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full)
if (strncmp(url, "iscsi://", 8)) { if (strncmp(url, "iscsi://", 8)) {
if (full) { if (full) {
iscsi_set_error(iscsi, "Invalid URL %s\niSCSI URL must be of " iscsi_set_error(iscsi, "Invalid URL %s\niSCSI URL must "
"the form: %s",url,ISCSI_URL_SYNTAX); } "be of the form: %s",
else { url, ISCSI_URL_SYNTAX);
iscsi_set_error(iscsi, "Invalid URL %s\niSCSI Portal URL must be of " } else {
"the form: %s",url,ISCSI_PORTAL_URL_SYNTAX); } iscsi_set_error(iscsi, "Invalid URL %s\niSCSI Portal "
"URL must be of the form: %s",
url, ISCSI_PORTAL_URL_SYNTAX);
}
return NULL; return NULL;
} }
strncpy(str,url + 8,MAX_STRING_SIZE); strncpy(str,url + 8, MAX_STRING_SIZE);
portal = str; portal = str;
user = getenv("LIBISCSI_CHAP_USERNAME"); user = getenv("LIBISCSI_CHAP_USERNAME");
@@ -406,56 +448,56 @@ iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full)
if (full) { if (full) {
target = strchr(portal, '/'); target = strchr(portal, '/');
if (target == NULL) { if (target == NULL) {
iscsi_set_error(iscsi, "Invalid URL %s\nCould not parse " iscsi_set_error(iscsi, "Invalid URL %s\nCould not "
"'<target-iqn>'\niSCSI URL must be of the " "parse '<target-iqn>'\niSCSI URL must be of "
"form: %s", "the form: %s",
url, url, ISCSI_URL_SYNTAX);
ISCSI_URL_SYNTAX);
return NULL; return NULL;
} }
*target++ = 0; *target++ = 0;
if (*target == 0) { if (*target == 0) {
iscsi_set_error(iscsi, "Invalid URL %s\nCould not parse " iscsi_set_error(iscsi, "Invalid URL %s\nCould not "
"<target-iqn>\n" "parse <target-iqn>\niSCSI URL must be of the "
"iSCSI URL must be of the form: %s", "form: %s",
url, url, ISCSI_URL_SYNTAX);
ISCSI_URL_SYNTAX);
return NULL; return NULL;
} }
lun = strchr(target, '/'); lun = strchr(target, '/');
if (lun == NULL) { if (lun == NULL) {
iscsi_set_error(iscsi, "Invalid URL %s\nCould not parse <lun>\n" iscsi_set_error(iscsi, "Invalid URL %s\nCould not "
"iSCSI URL must be of the form: %s", "parse <lun>\niSCSI URL must be of the form: "
url, "%s",
ISCSI_URL_SYNTAX); url, ISCSI_URL_SYNTAX);
return NULL; return NULL;
} }
*lun++ = 0; *lun++ = 0;
l = strtol(lun, &tmp, 10); l = strtol(lun, &tmp, 10);
if (*lun == 0 || *tmp != 0) { if (*lun == 0 || *tmp != 0) {
iscsi_set_error(iscsi, "Invalid URL %s\nCould not parse <lun>\n" iscsi_set_error(iscsi, "Invalid URL %s\nCould not "
"iSCSI URL must be of the form: %s", "parse <lun>\niSCSI URL must be of the form: "
url, "%s",
ISCSI_URL_SYNTAX); url, ISCSI_URL_SYNTAX);
return NULL; return NULL;
} }
} } else {
else
{
tmp=strchr(portal,'/'); tmp=strchr(portal,'/');
if (tmp) *tmp=0; if (tmp) {
*tmp=0;
}
} }
if (iscsi != NULL) if (iscsi != NULL) {
iscsi_url = iscsi_malloc(iscsi, sizeof(struct iscsi_url)); iscsi_url = iscsi_malloc(iscsi, sizeof(struct iscsi_url));
else } else {
iscsi_url = malloc(sizeof(struct iscsi_url)); iscsi_url = malloc(sizeof(struct iscsi_url));
}
if (iscsi_url == NULL) { if (iscsi_url == NULL) {
iscsi_set_error(iscsi, "Out-of-memory: Failed to allocate iscsi_url structure"); iscsi_set_error(iscsi, "Out-of-memory: Failed to allocate "
"iscsi_url structure");
return NULL; return NULL;
} }
memset(iscsi_url, 0, sizeof(struct iscsi_url)); memset(iscsi_url, 0, sizeof(struct iscsi_url));
@@ -464,15 +506,17 @@ iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full)
strncpy(iscsi_url->portal,portal,MAX_STRING_SIZE); strncpy(iscsi_url->portal,portal,MAX_STRING_SIZE);
if (user != NULL && passwd != NULL) { if (user != NULL && passwd != NULL) {
strncpy(iscsi_url->user,user,MAX_STRING_SIZE); strncpy(iscsi_url->user, user, MAX_STRING_SIZE);
strncpy(iscsi_url->passwd,passwd,MAX_STRING_SIZE); strncpy(iscsi_url->passwd, passwd, MAX_STRING_SIZE);
} }
if (full) { if (full) {
strncpy(iscsi_url->target,target,MAX_STRING_SIZE); strncpy(iscsi_url->target, target, MAX_STRING_SIZE);
iscsi_url->lun = l; iscsi_url->lun = l;
} }
iscsi_decode_url_string(&iscsi_url->target[0]);
return iscsi_url; return iscsi_url;
} }

View File

@@ -622,6 +622,7 @@ h2i(int h)
} }
return h - '0'; return h - '0';
} }
static int static int
i2h(int i) i2h(int i)
{ {