Diff for /embedaddon/istgt/src/istgtcontrol.c between versions 1.1.1.1 and 1.1.1.3

version 1.1.1.1, 2012/02/21 16:42:02 version 1.1.1.3, 2013/07/21 23:49:22
Line 1 Line 1
 /*  /*
 * Copyright (C) 2008-2010 Daisuke Aoyama <aoyama@peach.ne.jp>. * Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>.
  * All rights reserved.   * All rights reserved.
  *   *
  * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
Line 40 Line 40
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
 #include <unistd.h>  #include <unistd.h>
   #include <syslog.h>
 #include <sys/types.h>  #include <sys/types.h>
   
 #include "istgt.h"  #include "istgt.h"
Line 49 Line 50
 #include "istgt_misc.h"  #include "istgt_misc.h"
 #include "istgt_md5.h"  #include "istgt_md5.h"
   
   #if !defined(__GNUC__)
   #undef __attribute__
   #define __attribute__(x)
   #endif
   
 //#define TRACE_UCTL  //#define TRACE_UCTL
   
 #define DEFAULT_UCTL_CONFIG BUILD_ETC_ISTGT "/istgtcontrol.conf"  #define DEFAULT_UCTL_CONFIG BUILD_ETC_ISTGT "/istgtcontrol.conf"
Line 118  typedef struct istgt_uctl_t { Line 124  typedef struct istgt_uctl_t {
 typedef UCTL *UCTL_Ptr;  typedef UCTL *UCTL_Ptr;
   
   
   static void fatal(const char *format, ...) __attribute__((__noreturn__, __format__(__printf__, 1, 2)));
   
 static void  static void
 fatal(const char *format, ...)  fatal(const char *format, ...)
 {  {
Line 148  uctl_readline(UCTL_Ptr uctl) Line 156  uctl_readline(UCTL_Ptr uctl)
         ssize_t total;          ssize_t total;
   
         total = istgt_readline_socket(uctl->sock, uctl->recvbuf, uctl->recvbufsize,          total = istgt_readline_socket(uctl->sock, uctl->recvbuf, uctl->recvbufsize,
                                                                  uctl->recvtmp, uctl->recvtmpsize,            uctl->recvtmp, uctl->recvtmpsize,
                                                                  &uctl->recvtmpidx, &uctl->recvtmpcnt,            &uctl->recvtmpidx, &uctl->recvtmpcnt,
                                                                  uctl->timeout);            uctl->timeout);
         if (total < 0) {          if (total < 0) {
                 return UCTL_CMD_DISCON;                  return UCTL_CMD_DISCON;
         }          }
Line 177  uctl_writeline(UCTL_Ptr uctl) Line 185  uctl_writeline(UCTL_Ptr uctl)
         return UCTL_CMD_OK;          return UCTL_CMD_OK;
 }  }
   
   static int uctl_snprintf(UCTL_Ptr uctl, const char *format, ...) __attribute__((__format__(__printf__, 2, 3)));
   
 static int  static int
 uctl_snprintf(UCTL_Ptr uctl, const char *format, ...)  uctl_snprintf(UCTL_Ptr uctl, const char *format, ...)
 {  {
Line 204  get_banner(UCTL_Ptr uctl) Line 214  get_banner(UCTL_Ptr uctl)
 }  }
   
 static int  static int
is_err_req_auth(UCTL_Ptr uctl, char *s)is_err_req_auth(UCTL_Ptr uctl __attribute__((__unused__)), char *s)
 {  {
         const char *req_auth_string = "auth required";          const char *req_auth_string = "auth required";
   
Line 217  is_err_req_auth(UCTL_Ptr uctl, char *s) Line 227  is_err_req_auth(UCTL_Ptr uctl, char *s)
 }  }
   
 static int  static int
is_err_chap_seq(UCTL_Ptr uctl, char *s)is_err_chap_seq(UCTL_Ptr uctl __attribute__((__unused__)), char *s)
 {  {
         const char *chap_seq_string = "CHAP sequence error";          const char *chap_seq_string = "CHAP sequence error";
   
Line 348  exec_unload(UCTL_Ptr uctl) Line 358  exec_unload(UCTL_Ptr uctl)
                 return UCTL_CMD_ERR;                  return UCTL_CMD_ERR;
         }          }
         uctl_snprintf(uctl, "UNLOAD \"%s\" %d\n",          uctl_snprintf(uctl, "UNLOAD \"%s\" %d\n",
                                  uctl->iqn, uctl->lun);            uctl->iqn, uctl->lun);
         rc = uctl_writeline(uctl);          rc = uctl_writeline(uctl);
         if (rc != UCTL_CMD_OK) {          if (rc != UCTL_CMD_OK) {
                 return rc;                  return rc;
Line 384  exec_load(UCTL_Ptr uctl) Line 394  exec_load(UCTL_Ptr uctl)
                 return UCTL_CMD_ERR;                  return UCTL_CMD_ERR;
         }          }
         uctl_snprintf(uctl, "LOAD \"%s\" %d\n",          uctl_snprintf(uctl, "LOAD \"%s\" %d\n",
                                  uctl->iqn, uctl->lun);            uctl->iqn, uctl->lun);
         rc = uctl_writeline(uctl);          rc = uctl_writeline(uctl);
         if (rc != UCTL_CMD_OK) {          if (rc != UCTL_CMD_OK) {
                 return rc;                  return rc;
Line 468  exec_change(UCTL_Ptr uctl) Line 478  exec_change(UCTL_Ptr uctl)
                 return UCTL_CMD_ERR;                  return UCTL_CMD_ERR;
         }          }
         uctl_snprintf(uctl, "CHANGE \"%s\" %d \"%s\" "          uctl_snprintf(uctl, "CHANGE \"%s\" %d \"%s\" "
                                  "\"%s\" \"%s\" \"%s\"\n",            "\"%s\" \"%s\" \"%s\"\n",
                                  uctl->iqn, uctl->lun, uctl->mtype,            uctl->iqn, uctl->lun, uctl->mtype,
                                  uctl->mflags, uctl->mfile, uctl->msize);            uctl->mflags, uctl->mfile, uctl->msize);
         rc = uctl_writeline(uctl);          rc = uctl_writeline(uctl);
         if (rc != UCTL_CMD_OK) {          if (rc != UCTL_CMD_OK) {
                 return rc;                  return rc;
Line 506  exec_reset(UCTL_Ptr uctl) Line 516  exec_reset(UCTL_Ptr uctl)
                 return UCTL_CMD_ERR;                  return UCTL_CMD_ERR;
         }          }
         uctl_snprintf(uctl, "RESET \"%s\" %d\n",          uctl_snprintf(uctl, "RESET \"%s\" %d\n",
                                  uctl->iqn, uctl->lun);            uctl->iqn, uctl->lun);
         rc = uctl_writeline(uctl);          rc = uctl_writeline(uctl);
         if (rc != UCTL_CMD_OK) {          if (rc != UCTL_CMD_OK) {
                 return rc;                  return rc;
Line 619  do_auth(UCTL_Ptr uctl) Line 629  do_auth(UCTL_Ptr uctl)
   
 #ifdef TRACE_UCTL  #ifdef TRACE_UCTL
         printf("do_auth: user=%s, secret=%s, muser=%s, msecret=%s\n",          printf("do_auth: user=%s, secret=%s, muser=%s, msecret=%s\n",
                   uctl->auth.user,            uctl->auth.user,
                   uctl->auth.secret,            uctl->auth.secret,
                   uctl->auth.muser,            uctl->auth.muser,
                   uctl->auth.msecret);            uctl->auth.msecret);
 #endif /* TRACE_UCTL */  #endif /* TRACE_UCTL */
   
         /* send algorithm CHAP_A */          /* send algorithm CHAP_A */
         uctl_snprintf(uctl, "AUTH CHAP_A %d\n",          uctl_snprintf(uctl, "AUTH CHAP_A %d\n",
                                  algorithm);            algorithm);
         rc = uctl_writeline(uctl);          rc = uctl_writeline(uctl);
         if (rc != UCTL_CMD_OK) {          if (rc != UCTL_CMD_OK) {
                 return rc;                  return rc;
Line 662  do_auth(UCTL_Ptr uctl) Line 672  do_auth(UCTL_Ptr uctl)
         uctl->auth.chap_id[0] = (uint8_t) strtol(chap_i, NULL, 10);          uctl->auth.chap_id[0] = (uint8_t) strtol(chap_i, NULL, 10);
         /* Challenge Value */          /* Challenge Value */
         rc = istgt_hex2bin(uctl->auth.chap_challenge,          rc = istgt_hex2bin(uctl->auth.chap_challenge,
                                           UCTL_CHAP_CHALLENGE_LEN,            UCTL_CHAP_CHALLENGE_LEN,
                                           chap_c);            chap_c);
         if (rc < 0) {          if (rc < 0) {
                 fprintf(stderr, "challenge format error\n");                  fprintf(stderr, "challenge format error\n");
                 return UCTL_CMD_ERR;                  return UCTL_CMD_ERR;
Line 680  do_auth(UCTL_Ptr uctl) Line 690  do_auth(UCTL_Ptr uctl)
         istgt_md5update(&md5ctx, uctl->auth.chap_id, 1);          istgt_md5update(&md5ctx, uctl->auth.chap_id, 1);
         /* followed by secret */          /* followed by secret */
         istgt_md5update(&md5ctx, uctl->auth.secret,          istgt_md5update(&md5ctx, uctl->auth.secret,
                                        strlen(uctl->auth.secret));            strlen(uctl->auth.secret));
         /* followed by Challenge Value */          /* followed by Challenge Value */
         istgt_md5update(&md5ctx, uctl->auth.chap_challenge,          istgt_md5update(&md5ctx, uctl->auth.chap_challenge,
                                        uctl->auth.chap_challenge_len);            uctl->auth.chap_challenge_len);
         /* uctlmd5 is Response Value */          /* uctlmd5 is Response Value */
         istgt_md5final(uctlmd5, &md5ctx);          istgt_md5final(uctlmd5, &md5ctx);
   
Line 691  do_auth(UCTL_Ptr uctl) Line 701  do_auth(UCTL_Ptr uctl)
         worksize = uctl->worksize;          worksize = uctl->worksize;
   
         istgt_bin2hex(workp, worksize,          istgt_bin2hex(workp, worksize,
                                  uctlmd5, ISTGT_MD5DIGEST_LEN);            uctlmd5, ISTGT_MD5DIGEST_LEN);
         hexmd5 = workp;          hexmd5 = workp;
         worksize -= strlen(hexmd5) + 1;          worksize -= strlen(hexmd5) + 1;
         workp += strlen(hexmd5) + 1;          workp += strlen(hexmd5) + 1;
Line 704  do_auth(UCTL_Ptr uctl) Line 714  do_auth(UCTL_Ptr uctl)
                 /* (binary length MUST not exceed 1024 bytes) */                  /* (binary length MUST not exceed 1024 bytes) */
                 uctl->auth.chap_mchallenge_len = UCTL_CHAP_CHALLENGE_LEN;                  uctl->auth.chap_mchallenge_len = UCTL_CHAP_CHALLENGE_LEN;
                 istgt_gen_random(uctl->auth.chap_mchallenge,                  istgt_gen_random(uctl->auth.chap_mchallenge,
                                                 uctl->auth.chap_mchallenge_len);                    uctl->auth.chap_mchallenge_len);
   
                 istgt_bin2hex(workp, worksize,                  istgt_bin2hex(workp, worksize,
                                          uctl->auth.chap_mchallenge,                    uctl->auth.chap_mchallenge,
                                          uctl->auth.chap_mchallenge_len);                    uctl->auth.chap_mchallenge_len);
                 hexchallenge = workp;                  hexchallenge = workp;
                 worksize -= strlen(hexchallenge) + 1;                  worksize -= strlen(hexchallenge) + 1;
                 workp += strlen(hexchallenge) + 1;                  workp += strlen(hexchallenge) + 1;
   
                 /* send CHAP_NR with CHAP_IC */                  /* send CHAP_NR with CHAP_IC */
                 uctl_snprintf(uctl, "AUTH CHAP_NR %s %s %d %s\n",                  uctl_snprintf(uctl, "AUTH CHAP_NR %s %s %d %s\n",
                                          uctl->auth.user, hexmd5,                    uctl->auth.user, hexmd5,
                                          (int) uctl->auth.chap_mid[0], hexchallenge);                    (int) uctl->auth.chap_mid[0], hexchallenge);
                 rc = uctl_writeline(uctl);                  rc = uctl_writeline(uctl);
                 if (rc != UCTL_CMD_OK) {                  if (rc != UCTL_CMD_OK) {
                         return rc;                          return rc;
Line 763  do_auth(UCTL_Ptr uctl) Line 773  do_auth(UCTL_Ptr uctl)
                 istgt_md5update(&md5ctx, uctl->auth.chap_mid, 1);                  istgt_md5update(&md5ctx, uctl->auth.chap_mid, 1);
                 /* followed by secret */                  /* followed by secret */
                 istgt_md5update(&md5ctx, uctl->auth.msecret,                  istgt_md5update(&md5ctx, uctl->auth.msecret,
                                                strlen(uctl->auth.msecret));                    strlen(uctl->auth.msecret));
                 /* followed by Challenge Value */                  /* followed by Challenge Value */
                 istgt_md5update(&md5ctx, uctl->auth.chap_mchallenge,                  istgt_md5update(&md5ctx, uctl->auth.chap_mchallenge,
                                                uctl->auth.chap_mchallenge_len);                    uctl->auth.chap_mchallenge_len);
                 /* uctlmd5 is expecting Response Value */                  /* uctlmd5 is expecting Response Value */
                 istgt_md5final(uctlmd5, &md5ctx);                  istgt_md5final(uctlmd5, &md5ctx);
   
Line 792  do_auth(UCTL_Ptr uctl) Line 802  do_auth(UCTL_Ptr uctl)
                 /* not mutual */                  /* not mutual */
                 /* send CHAP_NR */                  /* send CHAP_NR */
                 uctl_snprintf(uctl, "AUTH CHAP_NR %s %s\n",                  uctl_snprintf(uctl, "AUTH CHAP_NR %s %s\n",
                                          uctl->auth.user, hexmd5);                    uctl->auth.user, hexmd5);
                 rc = uctl_writeline(uctl);                  rc = uctl_writeline(uctl);
                 if (rc != UCTL_CMD_OK) {                  if (rc != UCTL_CMD_OK) {
                         return rc;                          return rc;
Line 984  uctl_init(UCTL_Ptr uctl) Line 994  uctl_init(UCTL_Ptr uctl)
                                 uctl->req_auth_auto = 1;                                  uctl->req_auth_auto = 1;
                                 uctl->req_auth = 0;                                  uctl->req_auth = 0;
                                 uctl->req_auth_mutual = 0;                                  uctl->req_auth_mutual = 0;
                           } else if (strcasecmp(val, "None") == 0) {
                                   uctl->req_auth = 0;
                                   uctl->req_auth_mutual = 0;
                         } else {                          } else {
                                 fprintf(stderr, "unknown auth\n");                                  fprintf(stderr, "unknown auth\n");
                                 return -1;                                  return -1;
Line 999  uctl_init(UCTL_Ptr uctl) Line 1012  uctl_init(UCTL_Ptr uctl)
                 printf("AuthMethod Auto\n");                  printf("AuthMethod Auto\n");
         } else {          } else {
                 printf("AuthMethod %s %s\n",                  printf("AuthMethod %s %s\n",
                           uctl->req_auth ? "CHAP" : "",                    uctl->req_auth ? "CHAP" : "",
                           uctl->req_auth_mutual ? "Mutual" : "");                    uctl->req_auth_mutual ? "Mutual" : "");
         }          }
 #endif /* TRACE_UCTL */  #endif /* TRACE_UCTL */
   
Line 1019  uctl_init(UCTL_Ptr uctl) Line 1032  uctl_init(UCTL_Ptr uctl)
         uctl->auth.msecret = xstrdup(msecret);          uctl->auth.msecret = xstrdup(msecret);
 #ifdef TRACE_UCTL  #ifdef TRACE_UCTL
         printf("user=%s, secret=%s, muser=%s, msecret=%s\n",          printf("user=%s, secret=%s, muser=%s, msecret=%s\n",
                   user, secret, muser, msecret);            user, secret, muser, msecret);
 #endif /* TRACE_UCTL */  #endif /* TRACE_UCTL */
   
         return 0;          return 0;
Line 1094  main(int argc, char *argv[]) Line 1107  main(int argc, char *argv[])
   
 #ifdef HAVE_SETPROCTITLE  #ifdef HAVE_SETPROCTITLE
         setproctitle("version %s (%s)",          setproctitle("version %s (%s)",
                                 ISTGT_VERSION, ISTGT_EXTRA_VERSION);            ISTGT_VERSION, ISTGT_EXTRA_VERSION);
 #endif  #endif
   
         memset(&xuctl, 0, sizeof xuctl);          memset(&xuctl, 0, sizeof xuctl);
Line 1120  main(int argc, char *argv[]) Line 1133  main(int argc, char *argv[])
                         break;                          break;
                 case 'l':                  case 'l':
                         l = strtol(optarg, NULL, 10);                          l = strtol(optarg, NULL, 10);
                        if (l < 0 || l > 0x3fffU) {                        if (l < 0 || l > 0x3fff) {
                                 fatal("invalid lun %s\n", optarg);                                  fatal("invalid lun %s\n", optarg);
                         }                          }
                         lun = (int) l;                          lun = (int) l;
Line 1141  main(int argc, char *argv[]) Line 1154  main(int argc, char *argv[])
                         if (strcasecmp(optarg, "CHAP") == 0) {                          if (strcasecmp(optarg, "CHAP") == 0) {
                                 req_auth = 1;                                  req_auth = 1;
                         } else if (strcasecmp(optarg, "Mutual") == 0                          } else if (strcasecmp(optarg, "Mutual") == 0
                                           || strcasecmp(optarg, "Mutual CHAP") == 0                            || strcasecmp(optarg, "Mutual CHAP") == 0
                                           || strcasecmp(optarg, "CHAP Mutual") == 0) {                            || strcasecmp(optarg, "CHAP Mutual") == 0) {
                                 req_auth = 2;                                  req_auth = 2;
                         } else if (strcasecmp(optarg, "Auto") == 0) {                          } else if (strcasecmp(optarg, "Auto") == 0) {
                                 req_auth = 0;                                  req_auth = 0;
Line 1173  main(int argc, char *argv[]) Line 1186  main(int argc, char *argv[])
                         break;                          break;
                 case 'V':                  case 'V':
                         printf("istgtcontrol version %s (%s)\n",                          printf("istgtcontrol version %s (%s)\n",
                                   ISTGT_VERSION, ISTGT_EXTRA_VERSION);                            ISTGT_VERSION, ISTGT_EXTRA_VERSION);
                         exit(EXIT_SUCCESS);                          exit(EXIT_SUCCESS);
                 case 'H':                  case 'H':
                 default:                  default:
Line 1199  main(int argc, char *argv[]) Line 1212  main(int argc, char *argv[])
         uctl->config = config;          uctl->config = config;
         //istgt_print_config(config);          //istgt_print_config(config);
   
           istgtcontrol_open_log();
   
         /* take specified command */          /* take specified command */
         if (argc < 1) {          if (argc < 1) {
         error_usage_return:          error_usage_return:
Line 1247  main(int argc, char *argv[]) Line 1262  main(int argc, char *argv[])
         }          }
   
         /* build parameters */          /* build parameters */
        uctl_init(uctl);        rc = uctl_init(uctl);
         if (rc < 0) {
                 fprintf(stderr, "uctl_init() failed\n");
                 istgt_free_config(config);
                 exit(EXIT_FAILURE);
         }
         uctl->recvtmpcnt = 0;          uctl->recvtmpcnt = 0;
         uctl->recvtmpidx = 0;          uctl->recvtmpidx = 0;
         uctl->recvtmpsize = sizeof uctl->recvtmp;          uctl->recvtmpsize = sizeof uctl->recvtmp;
Line 1293  main(int argc, char *argv[]) Line 1313  main(int argc, char *argv[])
         }          }
 #ifdef TRACE_UCTL  #ifdef TRACE_UCTL
         printf("auto=%d, auth=%d, mutual=%d\n",          printf("auto=%d, auth=%d, mutual=%d\n",
                   uctl->req_auth_auto, uctl->req_auth, uctl->req_auth_mutual);            uctl->req_auth_auto, uctl->req_auth, uctl->req_auth_mutual);
 #endif /* TRACE_UCTL */  #endif /* TRACE_UCTL */
   
         if (host != NULL) {          if (host != NULL) {
Line 1331  main(int argc, char *argv[]) Line 1351  main(int argc, char *argv[])
         if (verbose) {          if (verbose) {
                 printf("iqn=%s, lun=%d\n", NULLP(uctl->iqn), uctl->lun);                  printf("iqn=%s, lun=%d\n", NULLP(uctl->iqn), uctl->lun);
                 printf("media file=%s, flags=%s, size=%s\n",                  printf("media file=%s, flags=%s, size=%s\n",
                           NULLP(uctl->mfile), NULLP(uctl->mflags), NULLP(uctl->msize));                    NULLP(uctl->mfile), NULLP(uctl->mflags), NULLP(uctl->msize));
         }          }
   
         /* set signals */          /* set signals */
Line 1434  main(int argc, char *argv[]) Line 1454  main(int argc, char *argv[])
         xfree(banner);          xfree(banner);
         xfree(cmd);          xfree(cmd);
         istgt_free_config(config);          istgt_free_config(config);
           istgtcontrol_close_log();
   
         /* return value as execution result */          /* return value as execution result */
         if (exec_result != UCTL_CMD_OK) {          if (exec_result != UCTL_CMD_OK) {

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>