Example #1
0
static gss_client_response *other_error(const char *fmt, ...)
{
    size_t needed;
    char *msg;
    gss_client_response *response = NULL;
    va_list ap, aps;

    va_start(ap, fmt);

    va_copy(aps, ap);
    needed = snprintf(NULL, 0, fmt, aps);
    va_end(aps);

    msg = malloc(needed);
    if (!msg) die1("Memory allocation failed");

    vsnprintf(msg, needed, fmt, ap);
    va_end(ap);

    response = calloc(1, sizeof(gss_client_response));
    if(response == NULL) die1("Memory allocation failed");
    response->message = msg;

    // TODO: something other than AUTH_GSS_ERROR?
    response->return_code = AUTH_GSS_ERROR;

    return response;
}
Example #2
0
int main(int argc, char* argv[])
{
  const char* ip;
  const char* tmp;
  
  if (argc < 2) die1(1, "usage: relay-ctrl-check program [arguments]\n");
  log_ips = getenv("RELAY_CTRL_LOG_IPS") != 0;
  log_env = getenv("RELAY_CTRL_LOG_ENV") != 0;
  if (getenv("RELAYCLIENT") == 0) {
    expiry = 0;
    if ((tmp = getenv("RELAY_CTRL_EXPIRY")) != 0) expiry = atol(tmp);
    if (expiry <= 0) expiry = 900;
    if ((rc = getenv("RELAY_CTRL_RELAYCLIENT")) == 0) rc = "";
    if ((ip = getenv("TCPREMOTEIP")) == 0)
      warn1("$TCPREMOTEIP not set, not checking IP");
    else if (do_chdir(0))
      stat_ip(ip);
  }
  else {
    if (log_ips)
      msg1("$RELAYCLIENT already set, not checking IP");
  }
  execvp(argv[1], argv+1);
  die1(111, "execution of program failed!\n");
  return 111;
  argc = 0;
}
Example #3
0
int main(int argc, char* argv[])
{
  const char* dir;
  int fd;
  struct stat s;
  char fdstr[32];
  
  if (argc < 2) die1(1, "usage: relay-ctrl-chdir program [arguments]\n");
  if ((dir = getenv("RELAY_CTRL_DIR")) == 0)
    die1(111, "$RELAY_CTRL_DIR is not set.");
  else if ((fd = open(dir, O_RDONLY)) == -1)
    die3sys(111, "Could not open dir '", dir, "'");
  else if (fstat(fd, &s) == -1)
    die1sys(111, "Could not stat opened file");
  else if (!S_ISDIR(s.st_mode))
    die3(111, "'", dir, "' is not a directory");
  else {
    fd = move_high(fd);
    utoa2(fd, fdstr);
    if (setenv("RELAY_CTRL_DIR_FD", fdstr, 1) == -1)
      die1(111, "Could not set environment variable");
  }
  execvp(argv[1], argv+1);
  die1(111, "execution of program failed!\n");
  return 111;
  argc = 0;
}
Example #4
0
int main(int argc, char* argv[])
{
  if (argc < 5) usage("Too few parameters");
  if (argc > 7) usage("Too many parameters");
  logacct = getpwnam(argv[1]);
  maindir = argv[2];
  logdir = argv[3];
  if (maindir[0] != '/' || logdir[0] != '/')
    die1(1, "Directory names must start with /.");
  cvmpath = argv[4];
  if (argc > 5) {
    ip = argv[5];
    if (argc > 6) dochroot = argv[6];
  }
  if (!logacct) die1(1, "Unknown logacct user name");

  umask(0);

  if (mkdir(maindir, 0755) == -1) die1sys(1, "Error creating main directory");
  if (chmod(maindir, 01755) == -1)
    die1sys(1, "Error setting permissions on main directory");
  
  if (mkdir(logdir, 0700) == -1) die1sys(1, "Error creating log directory");
  if (chown(logdir, logacct->pw_uid, logacct->pw_gid) == -1)
    die1sys(1, "Error setting owner on log directory");

  if (chdir(maindir) == -1) die1sys(1, "Error changing to main directory");
  if (mkdir("log", 0755) == -1)
    die1sys(1, "Error creating log service directory");
  if (mkdir("env", 0755) == -1)
    die1sys(1, "Error creating env directory");

  start_file("run", 0755);
  obuf_put5s(&conf_out,
	     "#!/bin/sh\n"
	     "exec 2>&1\n"
	     "umask 022\n"
	     "exec \\\n"
	     "tcpserver -DRHv -llocalhost ", ip, " 21 \\\n"
	     "envdir ", maindir, "/env \\\n");
  obuf_put7s(&conf_out,
	     "softlimit -m 2000000 \\\n",
	     conf_bin, "/twoftpd-auth \\\n",
	     cvmpath, " \\\n",
	     conf_bin, "/twoftpd-xfer");
  end_file();

  make_file("log/run", 0755,
	    "#!/bin/sh\n"
	    "exec \\\n"
	    "setuidgid ", logacct->pw_name, " \\\n"
	    "multilog t ", logdir, 0, 0, 0);
  
  if (dochroot) make_fileu("env/CHROOT", 1);
  
  return 0;
}
Example #5
0
gss_client_response *gss_error(const char *func, const char *op, OM_uint32 err_maj, OM_uint32 err_min) {
  OM_uint32 maj_stat, min_stat;
  OM_uint32 msg_ctx = 0;
  gss_buffer_desc status_string;

  gss_client_response *response = calloc(1, sizeof(gss_client_response));
  if(response == NULL) die1("Memory allocation failed");
  
  char *message = NULL;
  message = calloc(1024, 1);
  if(message == NULL) die1("Memory allocation failed");

  response->message = message;

  int nleft = 1024;
  int n;

  n = snprintf(message, nleft, "%s(%s)", func, op);
  message += n;
  nleft -= n;

  do {
    maj_stat = gss_display_status (&min_stat,
                                   err_maj,
                                   GSS_C_GSS_CODE,
                                   GSS_C_NO_OID,
                                   &msg_ctx,
                                   &status_string);
    if(GSS_ERROR(maj_stat))
      break;
    
    n = snprintf(message, nleft, ": %.*s",
	    (int)status_string.length, (char*)status_string.value);
    message += n;
    nleft -= n;

    gss_release_buffer(&min_stat, &status_string);
    
    maj_stat = gss_display_status (&min_stat,
                                   err_min,
                                   GSS_C_MECH_CODE,
                                   GSS_C_NULL_OID,
                                   &msg_ctx,
                                   &status_string);
    if(!GSS_ERROR(maj_stat)) {
	n = snprintf(message, nleft, ": %.*s",
		(int)status_string.length, (char*)status_string.value);
	message += n;
	nleft -= n;

      gss_release_buffer(&min_stat, &status_string);
    }
  } while (!GSS_ERROR(maj_stat) && msg_ctx != 0);

  return response;
}
Example #6
0
void wait_inject(void)
{
  int status;
  if(inject_pid) {
    if(waitpid(inject_pid, &status, WUNTRACED) == -1)
      die1sys(111, "Could not wait for qmail-inject to exit");
    if(!WIFEXITED(status))
      die1(111, "qmail-inject crashed");
    if(WEXITSTATUS(status))
      die1(111, "qmail-inject exited with an error");
  }
}
Example #7
0
gss_client_response *gss_error(OM_uint32 err_maj, OM_uint32 err_min) {
  OM_uint32 maj_stat, min_stat;
  OM_uint32 msg_ctx = 0;
  gss_buffer_desc status_string;
  char *buf_maj = calloc(512, sizeof(char));
  if(buf_maj == NULL) die1("Memory allocation failed");
  char *buf_min = calloc(512, sizeof(char));
  if(buf_min == NULL) die1("Memory allocation failed");
  char *message = NULL;
  gss_client_response *response = calloc(1, sizeof(gss_client_response));
  if(response == NULL) die1("Memory allocation failed");

  do {
    maj_stat = gss_display_status (&min_stat,
                                   err_maj,
                                   GSS_C_GSS_CODE,
                                   GSS_C_NO_OID,
                                   &msg_ctx,
                                   &status_string);
    if(GSS_ERROR(maj_stat))
      break;

    strncpy(buf_maj, (char*) status_string.value, 512);
    gss_release_buffer(&min_stat, &status_string);

    maj_stat = gss_display_status (&min_stat,
                                   err_min,
                                   GSS_C_MECH_CODE,
                                   GSS_C_NULL_OID,
                                   &msg_ctx,
                                   &status_string);
    if(!GSS_ERROR(maj_stat)) {
      strncpy(buf_min, (char*) status_string.value , 512);
      gss_release_buffer(&min_stat, &status_string);
    }
  } while (!GSS_ERROR(maj_stat) && msg_ctx != 0);

  // Join the strings
  message = calloc(1026, 1);
  if(message == NULL) die1("Memory allocation failed");
  // Join the two messages
  sprintf(message, "%s, %s", buf_maj, buf_min);
  // Free data
  free(buf_min);
  free(buf_maj);
  // Set the message
  response->message = message;
  // Return the message
  return response;
}
Example #8
0
gss_client_response *authenticate_gss_client_clean(gss_client_state *state) {
  OM_uint32 min_stat;
  int ret = AUTH_GSS_COMPLETE;
  gss_client_response *response = NULL;
  
  if(state->context != GSS_C_NO_CONTEXT)
    gss_delete_sec_context(&min_stat, &state->context, GSS_C_NO_BUFFER);
  
  if(state->server_name != GSS_C_NO_NAME)
    gss_release_name(&min_stat, &state->server_name);
  
  if(state->username != NULL) {
    free(state->username);
    state->username = NULL;
  }

  if (state->response != NULL) {
    free(state->response);
    state->response = NULL;
  }
  
  if(response == NULL) {
    response = calloc(1, sizeof(gss_client_response));
    if(response == NULL) die1("Memory allocation failed");
    response->return_code = ret;    
  }

  return response;
}
Example #9
0
/*
char* server_principal_details(const char* service, const char* hostname)
{
    char match[1024];
    int match_len = 0;
    char* result = NULL;
    
    int code;
    krb5_context kcontext;
    krb5_keytab kt = NULL;
    krb5_kt_cursor cursor = NULL;
    krb5_keytab_entry entry;
    char* pname = NULL;
    
    // Generate the principal prefix we want to match
    snprintf(match, 1024, "%s/%s@", service, hostname);
    match_len = strlen(match);
    
    code = krb5_init_context(&kcontext);
    if (code)
    {
        PyErr_SetObject(KrbException_class, Py_BuildValue("((s:i))",
                                                          "Cannot initialize Kerberos5 context", code));
        return NULL;
    }
    
    if ((code = krb5_kt_default(kcontext, &kt)))
    {
        PyErr_SetObject(KrbException_class, Py_BuildValue("((s:i))",
                                                          "Cannot get default keytab", code));
        goto end;
    }
    
    if ((code = krb5_kt_start_seq_get(kcontext, kt, &cursor)))
    {
        PyErr_SetObject(KrbException_class, Py_BuildValue("((s:i))",
                                                          "Cannot get sequence cursor from keytab", code));
        goto end;
    }
    
    while ((code = krb5_kt_next_entry(kcontext, kt, &entry, &cursor)) == 0)
    {
        if ((code = krb5_unparse_name(kcontext, entry.principal, &pname)))
        {
            PyErr_SetObject(KrbException_class, Py_BuildValue("((s:i))",
                                                              "Cannot parse principal name from keytab", code));
            goto end;
        }
        
        if (strncmp(pname, match, match_len) == 0)
        {
            result = malloc(strlen(pname) + 1);
            strcpy(result, pname);
            krb5_free_unparsed_name(kcontext, pname);
            krb5_free_keytab_entry_contents(kcontext, &entry);
            break;
        }
        
        krb5_free_unparsed_name(kcontext, pname);
        krb5_free_keytab_entry_contents(kcontext, &entry);
    }
    
    if (result == NULL)
    {
        PyErr_SetObject(KrbException_class, Py_BuildValue("((s:i))",
                                                          "Principal not found in keytab", -1));
    }
    
end:
    if (cursor)
        krb5_kt_end_seq_get(kcontext, kt, &cursor);
    if (kt)
        krb5_kt_close(kcontext, kt);
    krb5_free_context(kcontext);
    
    return result;
}
*/
gss_client_response *authenticate_gss_client_init(const char* service, long int gss_flags, gss_client_state* state) {
  OM_uint32 maj_stat;
  OM_uint32 min_stat;
  gss_buffer_desc name_token = GSS_C_EMPTY_BUFFER;
  gss_client_response *response = NULL;
  int ret = AUTH_GSS_COMPLETE;

  state->server_name = GSS_C_NO_NAME;
  state->context = GSS_C_NO_CONTEXT;
  state->gss_flags = gss_flags;
  state->username = NULL;
  state->response = NULL;
  
  // Import server name first
  name_token.length = strlen(service);
  name_token.value = (char *)service;
  
  maj_stat = gss_import_name(&min_stat, &name_token, gss_krb5_nt_service_name, &state->server_name);
  
  if (GSS_ERROR(maj_stat)) {
    response = gss_error(__func__, "gss_import_name", maj_stat, min_stat);
    response->return_code = AUTH_GSS_ERROR;
    goto end;
  }
  
end:
  if(response == NULL) {
    response = calloc(1, sizeof(gss_client_response));
    if(response == NULL) die1("Memory allocation failed");
    response->return_code = ret;    
  }

  return response;
}
Example #10
0
gss_client_response *authenticate_gss_client_unwrap(gss_client_state *state, const char *challenge) {
  OM_uint32 maj_stat;
  OM_uint32 min_stat;
  gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
  gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
  gss_client_response *response = NULL;
  int ret = AUTH_GSS_CONTINUE;
    
  // Always clear out the old response
  if(state->response != NULL) {
    free(state->response);
    state->response = NULL;
  }
    
  // If there is a challenge (data from the server) we need to give it to GSS
  if(challenge && *challenge) {
    int len;
    input_token.value = base64_decode(challenge, &len);
    input_token.length = len;
  }
    
  // Do GSSAPI step
  maj_stat = gss_unwrap(&min_stat,
                          state->context,
                          &input_token,
                          &output_token,
                          NULL,
                          NULL);
    
  if(maj_stat != GSS_S_COMPLETE) {
    response = gss_error(__func__, "gss_unwrap", maj_stat, min_stat);
    response->return_code = AUTH_GSS_ERROR;
    goto end;
  } else {
    ret = AUTH_GSS_COMPLETE;    
  }
    
  // Grab the client response
  if(output_token.length) {
    state->response = base64_encode((const unsigned char *)output_token.value, output_token.length);
    gss_release_buffer(&min_stat, &output_token);
  }
end:
  if(output_token.value)
    gss_release_buffer(&min_stat, &output_token);
  if(input_token.value)
    free(input_token.value);

  if(response == NULL) {
    response = calloc(1, sizeof(gss_client_response));
    if(response == NULL) die1("Memory allocation failed");
    response->return_code = ret;
  }

  // Return the response
  return response;
}
Example #11
0
int main(int argc, char* argv[])
{
  const char* bitstr;
  const char* polystr;
  int bits;
  int digits;
  uint64 poly;
  const char* suffix;
  int columns;
  char* end;
  int i;
  const char* name;
  int reflected;

  if (argc != 5) {
    msg3("usage: ", program, " NAME BITS POLY [normal|reflected]");
    return 1;
  }

  name = argv[1];

  bitstr = argv[2];
  bits = strtol(bitstr, &end, 0);
  if (*end != 0) die2(1, "Invalid bits value: ", bitstr);
  if (bits <= 0 || bits > 64) die1(1, "bits must be between 1 and 64");
  digits = (bits + 3) / 4;
  if (bits > 32) suffix = "ULL,";
  else if (bits > 16) suffix = "UL,";
  else suffix = "U,";
  columns = calc_columns(bits, suffix);

  polystr = argv[3];
  poly = strtoull(polystr, &end, 0);
  if (*end != 0) die2(1, "Invalid poly value: ", polystr);

  reflected = 0;
  if (strcasecmp(argv[4], "reflected") == 0)
    reflected = 1;
  else if (strcasecmp(argv[4], "normal") != 0)
    die2(1, "Must be either 'normal' or 'reflected': ", argv[4]);

  gentab(bits, poly, reflected);

  obuf_put3s(&outbuf, "#include \"", name, ".h\"\n\n");
  obuf_put5s(&outbuf, "const uint", bitstr, " ", name,
	     "_table[256] = {\n");
  for (i = 0; i < 256; ++i) {
    int column = i % columns;
    if (column == 0)
      obuf_puts(&outbuf, "  ");
    obuf_puts(&outbuf, "0x");
    if (bits > 32) {
      obuf_putxw(&outbuf, crctab[i]>>32, digits-8, '0');
      obuf_putxw(&outbuf, crctab[i] & 0xffffffffUL, 8, '0');
    }
    else
Example #12
0
static gss_client_response *krb5_ctx_error(krb5_context context, krb5_error_code problem)
{
    gss_client_response *response = NULL;
    const char *error_text = krb5_get_error_message(context, problem);
    response = calloc(1, sizeof(gss_client_response));
    if(response == NULL) die1("Memory allocation failed");
    response->message = strdup(error_text);
    // TODO: something other than AUTH_GSS_ERROR? AUTH_KRB5_ERROR ?
    response->return_code = AUTH_GSS_ERROR;
    krb5_free_error_message(context, error_text);
    return response;
}
Example #13
0
static gss_client_response *create_krb5_ccache(gss_server_state *state, krb5_context kcontext, krb5_principal princ, krb5_ccache *ccache)
{
    char *ccname = NULL;
    int fd;
    krb5_error_code problem;
    krb5_ccache tmp_ccache = NULL;
    gss_client_response *error = NULL;

    // TODO: mod_auth_kerb used a temp file under /run/httpd/krbcache. what can we do?
    ccname = strdup("FILE:/tmp/krb5cc_nodekerberos_XXXXXX");
    if (!ccname) die1("Memory allocation failed");

    fd = mkstemp(ccname + strlen("FILE:"));
    if (fd < 0) {
	error = other_error("mkstemp() failed: %s", strerror(errno));
	goto end;
    }

    close(fd);

    problem = krb5_cc_resolve(kcontext, ccname, &tmp_ccache);
    if (problem) {
       error = krb5_ctx_error(kcontext, problem);
       goto end;
    }

    problem = krb5_cc_initialize(kcontext, tmp_ccache, princ);
    if (problem) {
	error = krb5_ctx_error(kcontext, problem);
	goto end;
    }

    state->delegated_credentials_cache = strdup(ccname);

    // TODO: how/when to cleanup the creds cache file?
    // TODO: how to expose the credentials expiration time?

    *ccache = tmp_ccache;
    tmp_ccache = NULL;

 end:
    if (tmp_ccache)
	krb5_cc_destroy(kcontext, tmp_ccache);

    if (ccname && error)
	unlink(ccname);

    if (ccname)
	free(ccname);

    return error;
}
Example #14
0
static gss_client_response *store_gss_creds(gss_server_state *state)
{
    OM_uint32 maj_stat, min_stat;
    krb5_principal princ = NULL;
    krb5_ccache ccache = NULL;
    krb5_error_code problem;
    krb5_context context;
    gss_client_response *response = NULL;

    problem = krb5_init_context(&context);
    if (problem) {
	response = other_error("No auth_data value in request from client");
        return response;
    }

    problem = krb5_parse_name(context, state->username, &princ);
    if (problem) {
	response = krb5_ctx_error(context, problem);
	goto end;
    }

    if ((response = create_krb5_ccache(state, context, princ, &ccache)))
    {
	goto end;
    }

    maj_stat = gss_krb5_copy_ccache(&min_stat, state->client_creds, ccache);
    if (GSS_ERROR(maj_stat)) {
        response = gss_error(__func__, "gss_krb5_copy_ccache", maj_stat, min_stat);
        response->return_code = AUTH_GSS_ERROR;
        goto end;
    }

    krb5_cc_close(context, ccache);
    ccache = NULL;

    response = calloc(1, sizeof(gss_client_response));
    if(response == NULL) die1("Memory allocation failed");
    // TODO: something other than AUTH_GSS_COMPLETE?
    response->return_code = AUTH_GSS_COMPLETE;

 end:
    if (princ)
	krb5_free_principal(context, princ);
    if (ccache)
	krb5_cc_destroy(context, ccache);
    krb5_free_context(context);

    return response;
}
Example #15
0
int cli_main(int argc, char* argv[])
{
  nistp224key sec;
  nistp224key pub;
  obuf out;
  str str = {0,0,0};
  const char* home;
  const char* keypath;
  
  uskey_path = "secret";
  upkey_path = "public";
  
  if (argc > 0)
    keypath = argv[0];
  else {
    if ((home = getenv("HOME")) == 0) die1(1, "$HOME is not set.");
    if (chdir(home) != 0)
      die3sys(1, "Could not change directory to '", home, "'");
    mkdir(".srcmd", 0700);
    keypath = ".srcmd/key";
  }
  
  mkdir(keypath, 0755);
  if (chdir(keypath) != 0)
    die3sys(1, "Could not chdir to '", keypath, "'");
  
  random_key(sec);
  nistp224wrap(pub, BASEP224, sec);

  base64_encode_line(sec, sizeof sec, &str);
  if (!obuf_open(&out, uskey_path, OBUF_CREATE|OBUF_EXCLUSIVE, 0400, 0) ||
      !obuf_putstr(&out, &str) ||
      !obuf_putc(&out, '\n') ||
      !obuf_close(&out))
    die3sys(1, "Could not create secret key file '", uskey_path, "'");

  str_truncate(&str, 0);
  base64_encode_line(pub, sizeof pub, &str);
  if (!obuf_open(&out, upkey_path, OBUF_CREATE|OBUF_EXCLUSIVE, 0444, 0) ||
      !obuf_putstr(&out, &str) ||
      !obuf_putc(&out, '\n') ||
      !obuf_close(&out))
    die3sys(1, "Could not create public key file '", upkey_path, "'");
  
  msg3("Your public key is '", str.s, "'");
  
  return 0;
  argc = 1;
}
Example #16
0
/* State Machine ----------------------------------------------------------- */
static void mainloop(void)
{
  int state = STATE_DISCONNECTED;
  while (!exitasap) {
    debugf(DEBUG_STATE, "{Entering state }s", state_name[state]);
    switch (state) {
    case STATE_DISCONNECTED: state = do_negotiating(); break;
    case STATE_NEGOTIATED:   state = do_connecting(); break;
    case STATE_SENDING:      state = do_sending(); break;
    case STATE_CONNECTED:    state = do_connected(); break;
    case STATE_EXITING:      exitasap = 1; break;
    default: die1(1, "Illegal state");
    }
  }
}
Example #17
0
int main(int argc, char* argv[])
{
  struct connection conn;
  iopoll_fd fds[2];
  int selfpipe;
  int i;

  msg_debug_init();
  testmode = getenv("TESTMODE") != 0;

  if ((shell_argv = malloc((argc + 3) * sizeof *argv)) == 0)
    die_oom(111);
  for (i = 1; i < argc; ++i)
    shell_argv[i-1] = argv[i];
  for (; i < argc + 4; ++i)
    shell_argv[i-1] = 0;
  shell_argc = argc - 1;

  if ((path = getenv("PATH")) == 0)
    die1(111, "No PATH is set");
  if ((devnull = open("/dev/null", O_RDWR)) == -1)
    die1sys(111, "Could not open \"/dev/null\"");
  if (!nonblock_on(0))
    die1sys(111, "Could not set non-blocking status");
  if ((selfpipe = selfpipe_init()) == -1)
    die1sys(111, "Could not create self-pipe");
  init_slots();
  connection_init(&conn, 0, 0);
  fds[0].fd = 0;
  fds[0].events = IOPOLL_READ;
  fds[1].fd = selfpipe;
  fds[1].events = IOPOLL_READ;
  for (;;) {
    if (iopoll_restart(fds, 2, -1) == -1)
      die1sys(111, "Poll failed");
    if (fds[0].revents)
      if (connection_read(&conn, handle_packet) <= 0)
	break;
    if (fds[1].revents) {
      read(selfpipe, &i, 1);
      handle_child(WNOHANG);
    }
  }
  msg1("Waiting for remaining slots to complete");
  while (slots_used > 0)
    handle_child(0);
  return 0;
}
Example #18
0
int main(int argc, char* argv[])
{
  if ((ip = getenv("TCPREMOTEIP")) == 0 || (ip = validate_ip(ip)) == 0)
    die1(111, "Must be run from tcp-env or tcpserver.");
  if ((dir = getenv("RELAY_CTRL_DIR")) == 0)
    warn1("$RELAY_CTRL_DIR is not set.");
  else
    if (is_authenticated())
      make_file(ip, argc > 1);

  if (argc > 1) {
    execvp(argv[1], argv+1);
    return 111;
  }
  return 0;
}
Example #19
0
gss_client_response *authenticate_gss_server_clean(gss_server_state *state)
{
    OM_uint32 min_stat;
    int ret = AUTH_GSS_COMPLETE;
    gss_client_response *response = NULL;
    
    if (state->context != GSS_C_NO_CONTEXT)
        gss_delete_sec_context(&min_stat, &state->context, GSS_C_NO_BUFFER);
    if (state->server_name != GSS_C_NO_NAME)
        gss_release_name(&min_stat, &state->server_name);
    if (state->client_name != GSS_C_NO_NAME)
        gss_release_name(&min_stat, &state->client_name);
    if (state->server_creds != GSS_C_NO_CREDENTIAL)
        gss_release_cred(&min_stat, &state->server_creds);
    if (state->client_creds != GSS_C_NO_CREDENTIAL)
        gss_release_cred(&min_stat, &state->client_creds);
    if (state->username != NULL)
    {
        free(state->username);
        state->username = NULL;
    }
    if (state->targetname != NULL)
    {
        free(state->targetname);
        state->targetname = NULL;
    }
    if (state->response != NULL)
    {
        free(state->response);
        state->response = NULL;
    }
    if (state->delegated_credentials_cache)
    {
	// TODO: what about actually destroying the cache? It can't be done now as
	// the whole point is having it around for the lifetime of the "session"
	free(state->delegated_credentials_cache);
    }
    
    if(response == NULL) {
      response = calloc(1, sizeof(gss_client_response));
      if(response == NULL) die1("Memory allocation failed");
      response->return_code = ret;
    }

    // Return the response
    return response;
}
Example #20
0
/*
 * Convert a DNS name or numeric IP address into an integer value
 * (in network byte order).  This is more general-purpose than
 * inet_addr() which maps dotted pair notation to uint. 
 */
struct sockaddr *get_sockaddr(const char *s, int port, struct sockaddr *saddr) {
    struct sockaddr_in *sin = (struct sockaddr_in *)saddr;
    int ip;
    
	if (isdigit(*s)) {
		ip = (unsigned int)inet_addr(s);
    } else {
		struct hostent *hp = gethostbyname(s);
		if (hp == 0)
			die1("Can't translate %s to an address", s);
		ip = *((unsigned int **)hp->h_addr_list)[0];
    }
	
    memset((char *)sin, 0, sizeof(*sin));
    sin->sin_family = AF_INET;
    sin->sin_port = htons(port);
    sin->sin_addr.s_addr = ip;
    return saddr;
}
Example #21
0
static void load_keys(const char* server)
{
  str path = {0,0,0};

  wrap_str(str_copy4s(&path, keydir, "/servers/", server, "."));
  if (!keylist_load_multi(&server_publics, path.s, 0) &&
      !keylist_load_multi(&server_publics, "server.", 0))
    die1sys(1, "Could not load server keys");

  if (!keylist_load_multi(&client_secrets, "", 0)) {
    wrap_str(str_copy2s(&path, keydir, "/"));
    if (!keylist_load_multi(&client_secrets, path.s, 0))
      die1sys(1, "Could not load sender keys");
  }

  if (!keylist_exchange_all(&shared_secrets, &server_publics, &client_secrets))
    die1(1, "No server keys matched any sender keys");
  
  str_free(&path);
}
Example #22
0
void load_config(void)
{
  unsigned i;

  wrap_chdir(qmail_home);
  wrap_chdir("control");
  
  me = read_line("me");
  if(!*me)
    die1(111, "Could not read control/me");
  queuelifetime = read_int("queuelifetime", 604800);
  now = time(0);
  lastrun = read_int(opt_run_file, 0);
  
  if(extra_rcpt_name && *extra_rcpt_name) {
    if(strchr(extra_rcpt_name, '@'))
      extra_rcpt = extra_rcpt_name;
    else {
      char* er = malloc(strlen(extra_rcpt_name)+strlen(me)+2);
      strcpy(er, extra_rcpt_name);
      strcat(er, "@");
      strcat(er, me);
      extra_rcpt = er;
    }
  }
  else
    extra_rcpt = 0;

  if (opt_checkrcpt) load_rcpthosts();

  debug3(1, "me='", me, "'");
  debug2(1, "queuelifetime=", utoa(queuelifetime));
  debug3(1, "extra_rcpt='", extra_rcpt, "'");
  debug2(1, "now=", utoa(now));
  debug2(1, "lastrun=", utoa(lastrun));
  for (i = 0; i < opt_age_count; ++i)
    debug2(1, "opt_ages[]=", utoa(opt_ages[i]));
}
Example #23
0
int
main (
  int argc,
  char *argv[]
)
{
  int exit_val;
  fribidi_boolean file_found;
  char *s;
  FILE *IN;

  text_width = 80;
  do_break = true;
  do_pad = true;
  do_mirror = true;
  do_clean = false;
  do_reorder_nsm = false;
  show_input = false;
  show_visual = true;
  show_basedir = false;
  show_ltov = false;
  show_vtol = false;
  show_levels = false;
  char_set = "UTF-8";
  bol_text = NULL;
  eol_text = NULL;
  input_base_direction = FRIBIDI_PAR_ON;

  if ((s = (char *) getenv ("COLUMNS")))
    {
      int i;

      i = atoi (s);
      if (i > 0)
	text_width = i;
    }

#define CHARSETDESC 257
#define CAPRTL 258

  /* Parse the command line with getopt library */
  /* Must set argv[0], getopt uses it to generate error messages */
  argv[0] = appname;
  while (1)
    {
      int option_index = 0, c;
      static struct option long_options[] = {
	{"help", 0, 0, 'h'},
	{"version", 0, 0, 'V'},
	{"verbose", 0, 0, 'v'},
	{"debug", 0, 0, 'd'},
	{"test", 0, 0, 't'},
	{"charset", 1, 0, 'c'},
#if FRIBIDI_MAIN_USE_ICONV_H+0
#else
	{"charsetdesc", 1, 0, CHARSETDESC},
	{"caprtl", 0, 0, CAPRTL},
#endif /* FRIBIDI_MAIN_USE_ICONV_H */
	{"showinput", 0, (int *) (void *) &show_input, true},
	{"nopad", 0, (int *) (void *) &do_pad, false},
	{"nobreak", 0, (int *) (void *) &do_break, false},
	{"width", 1, 0, 'w'},
	{"bol", 1, 0, 'B'},
	{"eol", 1, 0, 'E'},
	{"nomirror", 0, (int *) (void *) &do_mirror, false},
	{"reordernsm", 0, (int *) (void *) &do_reorder_nsm, true},
	{"clean", 0, (int *) (void *) &do_clean, true},
	{"ltr", 0, (int *) (void *) &input_base_direction, FRIBIDI_PAR_LTR},
	{"rtl", 0, (int *) (void *) &input_base_direction, FRIBIDI_PAR_RTL},
	{"wltr", 0, (int *) (void *) &input_base_direction,
	 FRIBIDI_PAR_WLTR},
	{"wrtl", 0, (int *) (void *) &input_base_direction,
	 FRIBIDI_PAR_WRTL},
	{"basedir", 0, (int *) (void *) &show_basedir, true},
	{"ltov", 0, (int *) (void *) &show_ltov, true},
	{"vtol", 0, (int *) (void *) &show_vtol, true},
	{"levels", 0, (int *) (void *) &show_levels, true},
	{"novisual", 0, (int *) (void *) &show_visual, false},
	{0, 0, 0, 0}
      };

      c =
	getopt_long (argc, argv, "hVvdtc:w:B:E:", long_options,
		     &option_index);
      if (c == -1)
	break;

      switch (c)
	{
	case 0:
	  break;
	case 'h':
	  help ();
	  break;
	case 'V':
	  version ();
	  break;
	case 'v':
	  show_basedir = show_ltov = show_vtol = show_levels = true;
	  break;
	case 'w':
	  text_width = atoi (optarg);
	  if (text_width <= 0)
	    die2 ("invalid screen width `%s'\n", optarg);
	  break;
	case 'B':
	  bol_text = optarg;
	  break;
	case 'E':
	  eol_text = optarg;
	  break;
	case 'd':
	  if (!fribidi_set_debug (true))
	    die1
	      ("lib" FRIBIDI
	       " must be compiled with DEBUG option to enable\nturn debug info on.\n");
	  break;
	case 't':
	  do_clean = show_input = do_reorder_nsm = true;
	  do_break = false;
	  break;
	case 'c':
	  char_set = my_fribidi_strdup (optarg);
	  if (!char_set)
	    die1 ("memory allocation failed for char_set!");
	  break;
#if FRIBIDI_MAIN_USE_ICONV_H+0
#else
	case CAPRTL:
	  char_set = "CapRTL";
	  break;
	case CHARSETDESC:
	  char_set = optarg;
	  char_set_num = fribidi_parse_charset (char_set);
	  if (!char_set_num)
	    die2 ("unrecognized character set `%s'\n", char_set);
	  if (!fribidi_char_set_desc (char_set_num))
	    die2 ("no description available for character set `%s'\n",
		  fribidi_char_set_name (char_set_num));
	  else
	    printf ("Descriptions for character set %s:\n"
		    "\n" "%s", fribidi_char_set_title (char_set_num),
		    fribidi_char_set_desc (char_set_num));
	  exit (0);
	  break;
#endif /* !FRIBIDI_MAIN_USE_ICONV_H */
	case ':':
	case '?':
	  die2 (NULL, NULL);
	  break;
	default:
	  break;
	}
    }

#if FRIBIDI_MAIN_USE_ICONV_H+0
  to_ucs4 = iconv_open ("WCHAR_T", char_set);
  from_ucs4 = iconv_open (char_set, "WCHAR_T");
#else /* !FRIBIDI_MAIN_USE_ICONV_H */
  char_set_num = fribidi_parse_charset (char_set);
#endif /* !FRIBIDI_MAIN_USE_ICONV_H */

#if FRIBIDI_MAIN_USE_ICONV_H+0
  if (to_ucs4 == (iconv_t) (-1) || from_ucs4 == (iconv_t) (-1))
#else /* !FRIBIDI_MAIN_USE_ICONV_H */
  if (!char_set_num)
#endif /* !FRIBIDI_MAIN_USE_ICONV_H */
    die2 ("unrecognized character set `%s'\n", char_set);

  fribidi_set_mirroring (do_mirror);
  fribidi_set_reorder_nsm (do_reorder_nsm);
  exit_val = 0;
  file_found = false;
  while (optind < argc || !file_found)
    {
      const char *filename;

      filename = optind < argc ? argv[optind++] : "-";
      file_found = true;

      /* Open the infile for reading */
      if (filename[0] == '-' && !filename[1])
	{
	  IN = stdin;
	}
      else
	{
	  IN = fopen (filename, "r");
	  if (!IN)
	    {
	      fprintf (stderr, "%s: %s: no such file or directory\n",
		       appname, filename);
	      exit_val = 1;
	      continue;
	    }
	}

      /* Read and process input one line at a time */
      {
	char S_[MAX_STR_LEN];
	int padding_width, break_width;

	padding_width = show_input ? (text_width - 10) / 2 : text_width;
	break_width = do_break ? padding_width : 3 * MAX_STR_LEN;

	while (fgets (S_, sizeof (S_) - 1, IN))
	  {
	    const char *new_line, *nl_found;
	    FriBidiChar logical[MAX_STR_LEN];
	    char outstring[MAX_STR_LEN];
	    FriBidiParType base;
	    FriBidiStrIndex len;

	    nl_found = "";
	    S_[sizeof (S_) - 1] = 0;
	    len = strlen (S_);
	    /* chop */
	    if (S_[len - 1] == '\n')
	      {
		len--;
		S_[len] = '\0';
		new_line = "\n";
	      }
	    else
	      new_line = "";
	    /* TODO: handle \r */

#if FRIBIDI_MAIN_USE_ICONV_H+0
	    {
	      char *st = S_, *ust = (char *) logical;
	      int in_len = (int) len;
	      len = sizeof logical;
	      iconv (to_ucs4, &st, &in_len, &ust, (int *) &len);
	      len = (FriBidiChar *) ust - logical;
	    }
#else /* !FRIBIDI_MAIN_USE_ICONV_H */
	    len = fribidi_charset_to_unicode (char_set_num, S_, len, logical);
#endif /* !FRIBIDI_MAIN_USE_ICONV_H */

	    {
	      FriBidiChar *visual;
	      FriBidiStrIndex *ltov, *vtol;
	      FriBidiLevel *levels;
	      FriBidiStrIndex new_len;
	      fribidi_boolean log2vis;

	      visual = show_visual ? ALLOCATE (FriBidiChar,
					       len + 1
	      ) : NULL;
	      ltov = show_ltov ? ALLOCATE (FriBidiStrIndex,
					   len + 1
	      ) : NULL;
	      vtol = show_vtol ? ALLOCATE (FriBidiStrIndex,
					   len + 1
	      ) : NULL;
	      levels = show_levels ? ALLOCATE (FriBidiLevel,
					       len + 1
	      ) : NULL;

	      /* Create a bidi string. */
	      base = input_base_direction;
	      log2vis = fribidi_log2vis (logical, len, &base,
					 /* output */
					 visual, ltov, vtol, levels);
	      if (log2vis)
		{

		  if (show_input)
		    printf ("%-*s => ", padding_width, S_);

		  new_len = len;

		  /* Remove explicit marks, if asked for. */
		  if (do_clean)
		    len =
		      fribidi_remove_bidi_marks (visual, len, ltov, vtol,
						 levels);

		  if (show_visual)
		    {
		      printf ("%s", nl_found);

		      if (bol_text)
			printf ("%s", bol_text);

		      /* Convert it to input charset and print. */
		      {
			FriBidiStrIndex idx, st;
			for (idx = 0; idx < len;)
			  {
			    FriBidiStrIndex wid, inlen;

			    wid = break_width;
			    st = idx;
#if FRIBIDI_MAIN_USE_ICONV_H+0
#else
			    if (char_set_num != FRIBIDI_CHAR_SET_CAP_RTL)
#endif /* !FRIBIDI_MAIN_USE_ICONV_H */
			      while (wid > 0 && idx < len)
				{
				  wid -=
				    FRIBIDI_IS_EXPLICIT_OR_BN_OR_NSM
				    (fribidi_get_bidi_type (visual[idx])) ? 0
				    : 1;
				  idx++;
				}
#if FRIBIDI_MAIN_USE_ICONV_H+0
#else
			    else
			      while (wid > 0 && idx < len)
				{
				  wid--;
				  idx++;
				}
#endif /* !FRIBIDI_MAIN_USE_ICONV_H */
			    if (wid < 0 && idx > st + 1)
			      idx--;
			    inlen = idx - st;

#if FRIBIDI_MAIN_USE_ICONV_H+0
			    {
			      char *str = outstring, *ust =
				(char *) (visual + st);
			      int in_len = inlen * sizeof visual[0];
			      new_len = sizeof outstring;
			      iconv (from_ucs4, &ust, &in_len, &str,
				     (int *) &new_len);
			      *str = '\0';
			      new_len = str - outstring;
			    }
#else /* !FRIBIDI_MAIN_USE_ICONV_H */
			    new_len =
			      fribidi_unicode_to_charset (char_set_num,
							  visual + st, inlen,
							  outstring);
#endif /* !FRIBIDI_MAIN_USE_ICONV_H */
			    if (FRIBIDI_IS_RTL (base))
			      printf ("%*s",
				      (int) (do_pad ? (padding_width +
						       strlen (outstring) -
						       (break_width -
							wid)) : 0),
				      outstring);
			    else
			      printf ("%s", outstring);
			    if (idx < len)
			      printf ("\n");
			  }
		      }
		      if (eol_text)
			printf ("%s", eol_text);

		      nl_found = "\n";
		    }
		  if (show_basedir)
		    {
		      printf ("%s", nl_found);
		      printf ("Base direction: %s",
			      (FRIBIDI_DIR_TO_LEVEL (base) ? "R" : "L"));
		      nl_found = "\n";
		    }
		  if (show_ltov)
		    {
		      FriBidiStrIndex i;

		      printf ("%s", nl_found);
		      for (i = 0; i < len; i++)
			printf ("%ld ", (long) ltov[i]);
		      nl_found = "\n";
		    }
		  if (show_vtol)
		    {
		      FriBidiStrIndex i;

		      printf ("%s", nl_found);
		      for (i = 0; i < len; i++)
			printf ("%ld ", (long) vtol[i]);
		      nl_found = "\n";
		    }
		  if (show_levels)
		    {
		      FriBidiStrIndex i;

		      printf ("%s", nl_found);
		      for (i = 0; i < len; i++)
			printf ("%d ", (int) levels[i]);
		      nl_found = "\n";
		    }
		}
	      else
		{
		  exit_val = 2;
		}

	      if (show_visual)
		free (visual);
	      if (show_ltov)
		free (ltov);
	      if (show_vtol)
		free (vtol);
	      if (show_levels)
		free (levels);
	    }

	    if (*nl_found)
	      printf (new_line);
	  }
      }
    }

  return exit_val;
}
Example #24
0
/*
 * username, password: Credentials to validate. Null not allowed
 * service: Service principal (e.g. HTTP/somehost.example.org) of key
 *          stored in default keytab which will be used to verify KDC.
 *          Empty string (*not* NULL) will bypass KDC verification
 * return: response->return_code will be
 * 		-1 (AUTH_GSS_ERROR) for error, see response->message
 * 	 	0 for auth fail
 * 	 	1 for auth ok
 */
gss_client_response *authenticate_user_krb5_password(const char *username,
							 const char *password,
							 const char *service)
{
    krb5_context context = NULL;
    krb5_error_code problem;
    krb5_principal user_principal = NULL;
    krb5_get_init_creds_opt *opt = NULL;
    krb5_creds creds;
    bool auth_ok = false;

    gss_client_response *response = NULL;

    if (username == NULL || password == NULL || service == NULL) {
	return other_error("username, password and service must all be non-null");
    }

    memset(&creds, 0, sizeof(creds));

    problem = krb5_init_context(&context);
    if (problem) {
	// can't call krb5_ctx_error without a context...
	response = other_error("unable to initialize krb5 context (%d)", (int)problem);
	goto out;
    }

    problem = krb5_parse_name(context, username, &user_principal);
    if (problem) {
	response = krb5_ctx_error(context, problem);
	goto out;
    }

    problem = krb5_get_init_creds_opt_alloc(context, &opt);
    if (problem) {
	response = krb5_ctx_error(context, problem);
        goto out;
    }

    problem = krb5_get_init_creds_password(context, &creds, user_principal,
                                          (char *)password, NULL,
					  NULL, 0, NULL, opt);

    switch (problem) {
    case 0:
        auth_ok = true;
        break;
    case KRB5KDC_ERR_PREAUTH_FAILED:
    case KRB5KRB_AP_ERR_BAD_INTEGRITY:
    case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN:
        /* "expected" error */
        auth_ok = false;
        break;
    default:
	/* unexpected error */
	response = krb5_ctx_error(context, problem);
	break;
    }

    if (auth_ok && strlen(service) > 0) {
	response = verify_krb5_kdc(context, &creds, service);
    }

  out:
    krb5_free_cred_contents(context, &creds);

    if (opt != NULL) {
	krb5_get_init_creds_opt_free(context, opt);
    }

    if (user_principal != NULL) {
	krb5_free_principal(context, user_principal);
    }

    if (context != NULL) {
	krb5_free_context(context);
    }

    if (response == NULL) {
	response = calloc(1, sizeof(gss_client_response));
	if(response == NULL) die1("Memory allocation failed");
	response->return_code = auth_ok ? 1 : 0;
    }

    return response;
}
Example #25
0
void oom(void) { die1(111, "Out of memory"); }
Example #26
0
int cli_main(int argc, char* argv[])
{
  const char* server_name = 0;
  const char* env;

  msg_debug_init();
  encr_start();
  prep_sender();
  service = argv[0];
  if (argc > 1
      && argv[1][0] != '-'
      && argv[1][0] != '+') {
    server_name = argv[1];
    ++argv;
    --argc;
  }
  if (argc > 1)
    load_patterns(argv + 1);

  if (server_name == 0
      && (server_name = getenv("SERVER")) == 0)
    die1(1, "Server address not named on command line nor in $SERVER");
  if (!resolve_ipv4name(server_name, &ip))
    die3(1, "Could not resolve '", server_name, "'");

  brandom_init();
  if ((env = getenv("KEYDIR")) != 0)
    keydir = env;
  load_keys(server_name);

  if ((env = getenv("PORT")) != 0)
    port = strtoul(env, 0, 10);
  if (port == 0)
    port = 11014;
  if ((sock = socket_udp()) == -1)
    die1sys(1, "Could not create UDP socket");
  if (!socket_connect4(sock, &ip, port))
    die1sys(1, "Could not bind socket");
  if (!str_ready(&packet, 65535)
      || !str_ready(&rpacket, 4+4+8+256*5))
    die1(1, "Out of memory");

  getenvu("ACK_TIMEOUT", &ack_timeout);
  getenvu("CID_TIMEOUT", &cid_timeout);
  getenvu("RETRANSMITS", &retransmits);
  getenvu("READWAIT", &readwait);
  getenvu("STARTLINES", &startlines);
  if (getenv("EXITONEOF") != 0)
    exitoneof = 1;

  if (getenv("NOFILES") == 0 && getenv("NOFILE") == 0)
    buffer = buffer_file_init();
  else
    buffer = buffer_nofile_init();

  sig_all_catch(sigfn);
  exitasap = 0;

  mainloop();
  return 0;
}
Example #27
0
gss_client_response *authenticate_gss_client_step(gss_client_state* state, const char* challenge) {
  OM_uint32 maj_stat;
  OM_uint32 min_stat;
  gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
  gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
  int ret = AUTH_GSS_CONTINUE;
  gss_client_response *response = NULL;
  
  // Always clear out the old response
  if (state->response != NULL) {
    free(state->response);
    state->response = NULL;
  }
  
  // If there is a challenge (data from the server) we need to give it to GSS
  if (challenge && *challenge) {
    int len;
    input_token.value = base64_decode(challenge, &len);
    input_token.length = len;
  }
  
  // Do GSSAPI step
  maj_stat = gss_init_sec_context(&min_stat,
                                  GSS_C_NO_CREDENTIAL,
                                  &state->context,
                                  state->server_name,
                                  GSS_C_NO_OID,
                                  (OM_uint32)state->gss_flags,
                                  0,
                                  GSS_C_NO_CHANNEL_BINDINGS,
                                  &input_token,
                                  NULL,
                                  &output_token,
                                  NULL,
                                  NULL);

  if ((maj_stat != GSS_S_COMPLETE) && (maj_stat != GSS_S_CONTINUE_NEEDED)) {
    response = gss_error(__func__, "gss_init_sec_context", maj_stat, min_stat);
    response->return_code = AUTH_GSS_ERROR;
    goto end;
  }
  
  ret = (maj_stat == GSS_S_COMPLETE) ? AUTH_GSS_COMPLETE : AUTH_GSS_CONTINUE;
  // Grab the client response to send back to the server
  if(output_token.length) {
    state->response = base64_encode((const unsigned char *)output_token.value, output_token.length);
    maj_stat = gss_release_buffer(&min_stat, &output_token);
  }
  
  // Try to get the user name if we have completed all GSS operations
  if (ret == AUTH_GSS_COMPLETE) {
    gss_name_t gssuser = GSS_C_NO_NAME;
    maj_stat = gss_inquire_context(&min_stat, state->context, &gssuser, NULL, NULL, NULL,  NULL, NULL, NULL);
    
    if(GSS_ERROR(maj_stat)) {
      response = gss_error(__func__, "gss_inquire_context", maj_stat, min_stat);
      response->return_code = AUTH_GSS_ERROR;
      goto end;
    }
    
    gss_buffer_desc name_token;
    name_token.length = 0;
    maj_stat = gss_display_name(&min_stat, gssuser, &name_token, NULL);
    
    if(GSS_ERROR(maj_stat)) {
      if(name_token.value)
        gss_release_buffer(&min_stat, &name_token);
      gss_release_name(&min_stat, &gssuser);
      
      response = gss_error(__func__, "gss_display_name", maj_stat, min_stat);
      response->return_code = AUTH_GSS_ERROR;
      goto end;
    } else {
      state->username = (char *)malloc(name_token.length + 1);
      if(state->username == NULL) die1("Memory allocation failed");
      strncpy(state->username, (char*) name_token.value, name_token.length);
      state->username[name_token.length] = 0;
      gss_release_buffer(&min_stat, &name_token);
      gss_release_name(&min_stat, &gssuser);
    }
  }

end:
  if(output_token.value)
    gss_release_buffer(&min_stat, &output_token);
  if(input_token.value)
    free(input_token.value);

  if(response == NULL) {
    response = calloc(1, sizeof(gss_client_response));
    if(response == NULL) die1("Memory allocation failed");
    response->return_code = ret;
  }

  // Return the response
  return response;
}
Example #28
0
gss_client_response *authenticate_gss_client_wrap(gss_client_state* state, const char* challenge, const char* user) {
  OM_uint32 maj_stat;
  OM_uint32 min_stat;
  gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
  gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
  int ret = AUTH_GSS_CONTINUE;
  gss_client_response *response = NULL;
  char buf[4096], server_conf_flags;
  unsigned long buf_size;
    
  // Always clear out the old response
  if(state->response != NULL) {
    free(state->response);
    state->response = NULL;
  }
    
  if(challenge && *challenge) {
    int len;
    input_token.value = base64_decode(challenge, &len);
    input_token.length = len;
  }
    
  if(user) {
    // get bufsize
    server_conf_flags = ((char*) input_token.value)[0];
    ((char*) input_token.value)[0] = 0;
    buf_size = ntohl(*((long *) input_token.value));
    free(input_token.value);
#ifdef PRINTFS
    printf("User: %s, %c%c%c\n", user,
               server_conf_flags & GSS_AUTH_P_NONE      ? 'N' : '-',
               server_conf_flags & GSS_AUTH_P_INTEGRITY ? 'I' : '-',
               server_conf_flags & GSS_AUTH_P_PRIVACY   ? 'P' : '-');
    printf("Maximum GSS token size is %ld\n", buf_size);
#endif
        
    // agree to terms (hack!)
    buf_size = htonl(buf_size); // not relevant without integrity/privacy
    memcpy(buf, &buf_size, 4);
    buf[0] = GSS_AUTH_P_NONE;
    // server decides if principal can log in as user
    strncpy(buf + 4, user, sizeof(buf) - 4);
    input_token.value = buf;
    input_token.length = 4 + strlen(user);
  }
    
  // Do GSSAPI wrap
  maj_stat = gss_wrap(&min_stat,
            state->context,
            0,
            GSS_C_QOP_DEFAULT,
            &input_token,
            NULL,
            &output_token);
    
  if (maj_stat != GSS_S_COMPLETE) {
    response = gss_error(__func__, "gss_wrap", maj_stat, min_stat);
    response->return_code = AUTH_GSS_ERROR;
    goto end;
  } else
    ret = AUTH_GSS_COMPLETE;
  // Grab the client response to send back to the server
  if (output_token.length) {
    state->response = base64_encode((const unsigned char *)output_token.value, output_token.length);;
    gss_release_buffer(&min_stat, &output_token);
  }
end:
  if (output_token.value)
    gss_release_buffer(&min_stat, &output_token);

  if(response == NULL) {
    response = calloc(1, sizeof(gss_client_response));
    if(response == NULL) die1("Memory allocation failed");
    response->return_code = ret;
  }

  // Return the response
  return response;
}
Example #29
0
gss_client_response *authenticate_gss_server_init(const char *service, bool constrained_delegation, const char *username, gss_server_state *state)
{
    OM_uint32 maj_stat;
    OM_uint32 min_stat;
    gss_buffer_desc name_token = GSS_C_EMPTY_BUFFER;
    int ret = AUTH_GSS_COMPLETE;
    gss_client_response *response = NULL;
    gss_cred_usage_t usage = GSS_C_ACCEPT;

    state->context = GSS_C_NO_CONTEXT;
    state->server_name = GSS_C_NO_NAME;
    state->client_name = GSS_C_NO_NAME;
    state->server_creds = GSS_C_NO_CREDENTIAL;
    state->client_creds = GSS_C_NO_CREDENTIAL;
    state->username = NULL;
    state->targetname = NULL;
    state->response = NULL;
    state->constrained_delegation = constrained_delegation;
    state->delegated_credentials_cache = NULL;
    
    // Server name may be empty which means we aren't going to create our own creds
    size_t service_len = strlen(service);
    if (service_len != 0)
    {
        // Import server name first
        name_token.length = strlen(service);
        name_token.value = (char *)service;
        
        maj_stat = gss_import_name(&min_stat, &name_token, GSS_C_NT_HOSTBASED_SERVICE, &state->server_name);
        
        if (GSS_ERROR(maj_stat))
        {
            response = gss_error(__func__, "gss_import_name", maj_stat, min_stat);
            response->return_code = AUTH_GSS_ERROR;
            goto end;
        }
        
        if (state->constrained_delegation)
        {
            usage = GSS_C_BOTH;
        }

        // Get credentials
        maj_stat = gss_acquire_cred(&min_stat, state->server_name, GSS_C_INDEFINITE,
                                    GSS_C_NO_OID_SET, usage, &state->server_creds, NULL, NULL);

        if (GSS_ERROR(maj_stat))
        {
            response = gss_error(__func__, "gss_acquire_cred", maj_stat, min_stat);
            response->return_code = AUTH_GSS_ERROR;
            goto end;
        }
    }
    
    // If a username was passed, perform the S4U2Self protocol transition to acquire
    // a credentials from that user as if we had done gss_accept_sec_context.
    // In this scenario, the passed username is assumed to be already authenticated
    // by some external mechanism, and we are here to "bootstrap" some gss credentials.
    // In authenticate_gss_server_step we will bypass the actual authentication step.
    if (username != NULL)
    {
	gss_name_t gss_username;

	name_token.length = strlen(username);
	name_token.value = (char *)username;

	maj_stat = gss_import_name(&min_stat, &name_token, GSS_C_NT_USER_NAME, &gss_username);
	if (GSS_ERROR(maj_stat))
	{
	    response = gss_error(__func__, "gss_import_name", maj_stat, min_stat);
	    response->return_code = AUTH_GSS_ERROR;
	    goto end;
	}

	maj_stat = gss_acquire_cred_impersonate_name(&min_stat,
		state->server_creds,
		gss_username,
		GSS_C_INDEFINITE,
		GSS_C_NO_OID_SET,
		GSS_C_INITIATE,
		&state->client_creds,
		NULL,
		NULL);

	if (GSS_ERROR(maj_stat))
	{
	    response = gss_error(__func__, "gss_acquire_cred_impersonate_name", maj_stat, min_stat);
	    response->return_code = AUTH_GSS_ERROR;
	}

	gss_release_name(&min_stat, &gss_username);

	if (response != NULL)
	{
	    goto end;
	}

	// because the username MAY be a "local" username,
	// we want get the canonical name from the acquired creds.
	maj_stat = gss_inquire_cred(&min_stat, state->client_creds, &state->client_name, NULL, NULL, NULL);
	if (GSS_ERROR(maj_stat))
	{
	    response = gss_error(__func__, "gss_inquire_cred", maj_stat, min_stat);
	    response->return_code = AUTH_GSS_ERROR;
	    goto end;
	}
    }

end:
    if(response == NULL) {
      response = calloc(1, sizeof(gss_client_response));
      if(response == NULL) die1("Memory allocation failed");
      response->return_code = ret;
    }

    // Return the response
    return response;
}
Example #30
0
gss_client_response *authenticate_gss_server_step(gss_server_state *state, const char *auth_data)
{
    OM_uint32 maj_stat;
    OM_uint32 min_stat;
    gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
    int ret = AUTH_GSS_CONTINUE;
    gss_client_response *response = NULL;
    
    // Always clear out the old response
    if (state->response != NULL)
    {
        free(state->response);
        state->response = NULL;
    }
    
    // we don't need to check the authentication token if S4U2Self protocol
    // transition was done, because we already have the client credentials.
    if (state->client_creds == GSS_C_NO_CREDENTIAL)
    {
	if (auth_data && *auth_data)
	{
	    int len;
	    input_token.value = base64_decode(auth_data, &len);
	    input_token.length = len;
	}
	else
	{
	    response = calloc(1, sizeof(gss_client_response));
	    if(response == NULL) die1("Memory allocation failed");
	    response->message = strdup("No auth_data value in request from client");
	    response->return_code = AUTH_GSS_ERROR;
	    goto end;
	}

	maj_stat = gss_accept_sec_context(&min_stat,
					  &state->context,
					  state->server_creds,
					  &input_token,
					  GSS_C_NO_CHANNEL_BINDINGS,
					  &state->client_name,
					  NULL,
					  &output_token,
					  NULL,
					  NULL,
					  &state->client_creds);

	if (GSS_ERROR(maj_stat))
	{
	    response = gss_error(__func__, "gss_accept_sec_context", maj_stat, min_stat);
	    response->return_code = AUTH_GSS_ERROR;
	    goto end;
	}

	// Grab the server response to send back to the client
	if (output_token.length)
	{
	    state->response = base64_encode((const unsigned char *)output_token.value, output_token.length);
	    maj_stat = gss_release_buffer(&min_stat, &output_token);
	}
    }

    // Get the user name
    maj_stat = gss_display_name(&min_stat, state->client_name, &output_token, NULL);
    if (GSS_ERROR(maj_stat))
    {
	response = gss_error(__func__, "gss_display_name", maj_stat, min_stat);
	response->return_code = AUTH_GSS_ERROR;
	goto end;
    }
    state->username = (char *)malloc(output_token.length + 1);
    strncpy(state->username, (char*) output_token.value, output_token.length);
    state->username[output_token.length] = 0;

    // Get the target name if no server creds were supplied
    if (state->server_creds == GSS_C_NO_CREDENTIAL)
    {
	gss_name_t target_name = GSS_C_NO_NAME;
	maj_stat = gss_inquire_context(&min_stat, state->context, NULL, &target_name, NULL, NULL, NULL, NULL, NULL);
	if (GSS_ERROR(maj_stat))
	{
	    response = gss_error(__func__, "gss_inquire_context", maj_stat, min_stat);
	    response->return_code = AUTH_GSS_ERROR;
	    goto end;
	}
	maj_stat = gss_display_name(&min_stat, target_name, &output_token, NULL);
	if (GSS_ERROR(maj_stat))
	{
	    response = gss_error(__func__, "gss_display_name", maj_stat, min_stat);
	    response->return_code = AUTH_GSS_ERROR;
	    goto end;
	}
	state->targetname = (char *)malloc(output_token.length + 1);
	strncpy(state->targetname, (char*) output_token.value, output_token.length);
	state->targetname[output_token.length] = 0;
    }

    if (state->constrained_delegation && state->client_creds != GSS_C_NO_CREDENTIAL)
    {
	if ((response = store_gss_creds(state)) != NULL)
	{
	    goto end;
	}
    }

    ret = AUTH_GSS_COMPLETE;
    
end:
    if (output_token.length)
        gss_release_buffer(&min_stat, &output_token);
    if (input_token.value)
        free(input_token.value);

    if(response == NULL) {
      response = calloc(1, sizeof(gss_client_response));
      if(response == NULL) die1("Memory allocation failed");
      response->return_code = ret;
    }

    // Return the response
    return response;
}