Exemple #1
0
static int
unpack_cred(unsigned char *buf, int len, CREDENTIALS *cred)
{
    unsigned char *p = buf;

    p += krb_get_nir(p, cred->service, cred->instance, cred->realm);
    memcpy(cred->session, p, 8);
    p += 8;
    cred->lifetime = *p++;
    cred->kvno = *p++;
    p += krb_get_int(p, &cred->ticket_st.length, 4, 0);
    memcpy(cred->ticket_st.dat, p, cred->ticket_st.length);
    cred->ticket_st.mbz = 0;
    p += krb_get_int(p, (u_int32_t *)&cred->issue_date, 4, 0);
    p += krb_get_nir(p, cred->pname, cred->pinst, NULL);
    return 0;
}
Exemple #2
0
static int
krb4_auth(void *app_data, char *host)
{
    int ret;
    char *p;
    int len;
    KTEXT_ST adat;
    MSG_DAT msg_data;
    int checksum;
    uint32_t cs;
    struct krb4_data *d = app_data;
#ifdef HAVE_KRB_GET_OUR_IP_FOR_REALM
    struct sockaddr_in *localaddr  = (struct sockaddr_in *)LOCAL_ADDR;
/*  struct sockaddr_in *remoteaddr = (struct sockaddr_in *)REMOTE_ADDR;*/
#endif

    checksum = getpid();
    ret = mk_auth(d, &adat, "ftp", host, checksum);
    if(ret == KDC_PR_UNKNOWN)
	ret = mk_auth(d, &adat, "rcmd", host, checksum);
    if(ret){
	printf("%s\n", krb_get_err_text(ret));
	return AUTH_CONTINUE;
    }

#ifdef HAVE_KRB_GET_OUR_IP_FOR_REALM
    if (krb_get_config_bool("nat_in_use")) {
      struct in_addr natAddr;

      if (krb_get_our_ip_for_realm(krb_realmofhost(host),
				   &natAddr) != KSUCCESS
	  && krb_get_our_ip_for_realm(NULL, &natAddr) != KSUCCESS)
	ftp_err(_("Can't get address for realm %s\n"),
	       krb_realmofhost(host));
      else {
	if (natAddr.s_addr != localaddr->sin_addr.s_addr) {
	  ftp_err(_("Using NAT IP address (%s) for kerberos 4\n"),
		 inet_ntoa(natAddr));
	  localaddr->sin_addr = natAddr;
	}
      }
    }
#endif

   if(base64_encode(adat.dat, adat.length, &p) < 0) {
	ftp_err(_("Out of memory base64-encoding\n"));
	return AUTH_CONTINUE;
    }
    ret = ftp_cmd("ADAT %s", p);
    free(p);

    if(ftp->code != ctComplete){
	ftp_err(_("Server didn't accept auth data\n"));
	return AUTH_ERROR;
    }

    p = strstr(ftp->reply, "ADAT=");
    if(!p){
	ftp_err(_("Remote host didn't send adat reply\n"));
	return AUTH_ERROR;
    }
    p += 5;
    len = base64_decode(p, adat.dat);
    if(len < 0){
	ftp_err(_("Failed to decode base64 from server\n"));
	return AUTH_ERROR;
    }
    adat.length = len;
    ret = krb_rd_safe(adat.dat, adat.length, &d->key, 
		      (struct sockaddr_in *)hisctladdr, 
		      (struct sockaddr_in *)myctladdr, &msg_data);
    if(ret){
	ftp_err(_("Error reading reply from server: %s\n"),
	       krb_get_err_text(ret));
	return AUTH_ERROR;
    }
    krb_get_int(msg_data.app_data, &cs, 4, 0);
    if(cs - checksum != 1){
	ftp_err(_("Bad checksum returned from server\n"));
	return AUTH_ERROR;
    }
    return AUTH_OK;
}
Exemple #3
0
static int
krb4_auth(void *app_data, struct connectdata *conn)
{
  int ret;
  char *p;
  unsigned char *ptr;
  size_t len;
  KTEXT_ST adat;
  MSG_DAT msg_data;
  int checksum;
  u_int32_t cs;
  struct krb4_data *d = app_data;
  char *host = conn->host.name;
  ssize_t nread;
  int l = sizeof(conn->local_addr);
  struct SessionHandle *data = conn->data;
  CURLcode result;

  if(getsockname(conn->sock[FIRSTSOCKET],
                 (struct sockaddr *)LOCAL_ADDR, &l) < 0)
    perror("getsockname()");

  checksum = getpid();
  ret = mk_auth(d, &adat, "ftp", host, checksum);
  if(ret == KDC_PR_UNKNOWN)
    ret = mk_auth(d, &adat, "rcmd", host, checksum);
  if(ret) {
    infof(data, "%s\n", krb_get_err_text(ret));
    return AUTH_CONTINUE;
  }

#ifdef HAVE_KRB_GET_OUR_IP_FOR_REALM
  if(krb_get_config_bool("nat_in_use")) {
    struct sockaddr_in *localaddr  = (struct sockaddr_in *)LOCAL_ADDR;
    struct in_addr natAddr;

    if(krb_get_our_ip_for_realm(krb_realmofhost(host),
                                 &natAddr) != KSUCCESS
        && krb_get_our_ip_for_realm(NULL, &natAddr) != KSUCCESS)
      infof(data, "Can't get address for realm %s\n",
                 krb_realmofhost(host));
    else {
      if(natAddr.s_addr != localaddr->sin_addr.s_addr) {
        char addr_buf[128];
        if(Curl_inet_ntop(AF_INET, natAddr, addr_buf, sizeof(addr_buf)))
          infof(data, "Using NAT IP address (%s) for kerberos 4\n", addr_buf);
        localaddr->sin_addr = natAddr;
      }
    }
  }
#endif

  if(Curl_base64_encode(conn->data, (char *)adat.dat, adat.length, &p) < 1) {
    Curl_failf(data, "Out of memory base64-encoding");
    return AUTH_CONTINUE;
  }

  result = Curl_ftpsendf(conn, "ADAT %s", p);

  free(p);

  if(result)
    return -2;

  if(Curl_GetFTPResponse(&nread, conn, NULL))
    return -1;

  if(data->state.buffer[0] != '2'){
    Curl_failf(data, "Server didn't accept auth data");
    return AUTH_ERROR;
  }

  p = strstr(data->state.buffer, "ADAT=");
  if(!p) {
    Curl_failf(data, "Remote host didn't send adat reply");
    return AUTH_ERROR;
  }
  p += 5;
  len = Curl_base64_decode(p, &ptr);
  if(len > sizeof(adat.dat)-1) {
    free(ptr);
    len=0;
  }
  if(!len || !ptr) {
    Curl_failf(data, "Failed to decode base64 from server");
    return AUTH_ERROR;
  }
  memcpy((char *)adat.dat, ptr, len);
  free(ptr);
  adat.length = len;
  ret = krb_rd_safe(adat.dat, adat.length, &d->key,
                    (struct sockaddr_in *)hisctladdr,
                    (struct sockaddr_in *)myctladdr, &msg_data);
  if(ret) {
    Curl_failf(data, "Error reading reply from server: %s",
               krb_get_err_text(ret));
    return AUTH_ERROR;
  }
  krb_get_int(msg_data.app_data, &cs, 4, 0);
  if(cs - checksum != 1) {
    Curl_failf(data, "Bad checksum returned from server");
    return AUTH_ERROR;
  }
  return AUTH_OK;
}
Exemple #4
0
static int
krb4_auth(void *app_data, char *host)
{
    int ret;
    char *p;
    int len;
    KTEXT_ST adat;
    MSG_DAT msg_data;
    int checksum;
    uint32_t cs;
    struct krb4_data *d = app_data;
    struct sockaddr_in *localaddr  = (struct sockaddr_in *)LOCAL_ADDR;
    struct sockaddr_in *remoteaddr = (struct sockaddr_in *)REMOTE_ADDR;

    checksum = getpid();
    ret = mk_auth(d, &adat, "ftp", host, checksum);
    if(ret == KDC_PR_UNKNOWN)
	ret = mk_auth(d, &adat, "rcmd", host, checksum);
    if(ret){
	printf("%s\n", krb_get_err_text(ret));
	return AUTH_CONTINUE;
    }

#ifdef HAVE_KRB_GET_OUR_IP_FOR_REALM
    if (krb_get_config_bool("nat_in_use")) {
      struct in_addr natAddr;

      if (krb_get_our_ip_for_realm(krb_realmofhost(host),
				   &natAddr) != KSUCCESS
	  && krb_get_our_ip_for_realm(NULL, &natAddr) != KSUCCESS)
	printf("Can't get address for realm %s\n",
	       krb_realmofhost(host));
      else {
	if (natAddr.s_addr != localaddr->sin_addr.s_addr) {
	  printf("Using NAT IP address (%s) for kerberos 4\n",
		 inet_ntoa(natAddr));
	  localaddr->sin_addr = natAddr;
	  
	  /*
	   * This not the best place to do this, but it
	   * is here we know that (probably) NAT is in
	   * use!
	   */

	  passivemode = 1;
	  printf("Setting: Passive mode on.\n");
	}
      }
    }
#endif

    printf("Local address is %s\n", inet_ntoa(localaddr->sin_addr));
    printf("Remote address is %s\n", inet_ntoa(remoteaddr->sin_addr));

   if(base64_encode(adat.dat, adat.length, &p) < 0) {
	printf("Out of memory base64-encoding.\n");
	return AUTH_CONTINUE;
    }
    ret = command("ADAT %s", p);
    free(p);

    if(ret != COMPLETE){
	printf("Server didn't accept auth data.\n");
	return AUTH_ERROR;
    }

    p = strstr(reply_string, "ADAT=");
    if(!p){
	printf("Remote host didn't send adat reply.\n");
	return AUTH_ERROR;
    }
    p += 5;
    len = base64_decode(p, adat.dat);
    if(len < 0){
	printf("Failed to decode base64 from server.\n");
	return AUTH_ERROR;
    }
    adat.length = len;
    ret = krb_rd_safe(adat.dat, adat.length, &d->key, 
		      (struct sockaddr_in *)hisctladdr, 
		      (struct sockaddr_in *)myctladdr, &msg_data);
    if(ret){
	printf("Error reading reply from server: %s.\n", 
	       krb_get_err_text(ret));
	return AUTH_ERROR;
    }
    krb_get_int(msg_data.app_data, &cs, 4, 0);
    if(cs - checksum != 1){
	printf("Bad checksum returned from server.\n");
	return AUTH_ERROR;
    }
    return AUTH_OK;
}
Exemple #5
0
int32_t
krb_rd_safe(void *in, u_int32_t in_length, des_cblock *key, 
	    struct sockaddr_in *sender, struct sockaddr_in *receiver, 
	    MSG_DAT *m_data)
{
    unsigned char *p = (unsigned char*)in, *start;

    unsigned char pvno, type;
    int little_endian;
    struct timeval tv;
    u_int32_t src_addr;
    int delta_t;
    

    pvno = *p++;
    if(pvno != KRB_PROT_VERSION)
	return RD_AP_VERSION;
    
    type = *p++;
    little_endian = type & 1;
    type &= ~1;
    if(type != AUTH_MSG_SAFE)
	return RD_AP_MSG_TYPE;

    start = p;
    
    p += krb_get_int(p, &m_data->app_length, 4, little_endian);
    
    if(m_data->app_length + 31 > in_length)
	return RD_AP_MODIFIED;
    
    m_data->app_data = p;

    p += m_data->app_length;

    m_data->time_5ms = *p++;

    p += krb_get_address(p, &src_addr);

    if (!krb_equiv(src_addr, sender->sin_addr.s_addr))
        return RD_AP_BADD;

    p += krb_get_int(p, (u_int32_t *)&m_data->time_sec, 4, little_endian);
    m_data->time_sec = lsb_time(m_data->time_sec, sender, receiver);
    
    gettimeofday(&tv, NULL);

    delta_t = abs((int)((long) tv.tv_sec - m_data->time_sec));
    if (delta_t > CLOCK_SKEW) return RD_AP_TIME;

    /*
     * caller must check timestamps for proper order and replays, since
     * server might have multiple clients each with its own timestamps
     * and we don't assume tightly synchronized clocks.
     */

    {
	unsigned char new_checksum[16];
	unsigned char old_checksum[16];
	fixup_quad_cksum(start, p - start, key, 
			 new_checksum, old_checksum, little_endian);
	if((dqc_type == DES_QUAD_GUESS || dqc_type == DES_QUAD_NEW) && 
	   memcmp(new_checksum, p, 16) == 0)
	    dqc_type = DES_QUAD_NEW;
	else if((dqc_type == DES_QUAD_GUESS || dqc_type == DES_QUAD_OLD) && 
		memcmp(old_checksum, p, 16) == 0)
	    dqc_type = DES_QUAD_OLD;
	else
	    return RD_AP_MODIFIED;
    }
    return KSUCCESS;
}
Exemple #6
0
int32_t
krb_rd_priv(void *in, u_int32_t in_length, 
	    struct des_ks_struct *schedule, des_cblock *key, 
	    struct sockaddr_in *sender, struct sockaddr_in *receiver, 
	    MSG_DAT *m_data)
{
    unsigned char *p = (unsigned char*)in;
    int little_endian;
    u_int32_t clen;
    struct timeval tv;
    u_int32_t src_addr;
    int delta_t;

    unsigned char pvno, type;

    pvno = *p++;
    if(pvno != KRB_PROT_VERSION)
	return RD_AP_VERSION;
    
    type = *p++;
    little_endian = type & 1;
    type &= ~1;

    p += krb_get_int(p, &clen, 4, little_endian);
    
    if(clen + 2 > in_length)
	return RD_AP_MODIFIED;

    des_pcbc_encrypt((des_cblock*)p, (des_cblock*)p, clen, 
		     schedule, key, DES_DECRYPT);
    
    p += krb_get_int(p, &m_data->app_length, 4, little_endian);
    if(m_data->app_length + 17 > in_length)
	return RD_AP_MODIFIED;

    m_data->app_data = p;
    p += m_data->app_length;
    
    m_data->time_5ms = *p++;

    p += krb_get_address(p, &src_addr);

    if (!krb_equiv(src_addr, sender->sin_addr.s_addr))
	return RD_AP_BADD;

    p += krb_get_int(p, (u_int32_t *)&m_data->time_sec, 4, little_endian);

    m_data->time_sec = lsb_time(m_data->time_sec, sender, receiver);
    
    gettimeofday(&tv, NULL);

    /* check the time integrity of the msg */
    delta_t = abs((int)((long) tv.tv_sec - m_data->time_sec));
    if (delta_t > CLOCK_SKEW)
	return RD_AP_TIME;
    if (krb_debug)
	krb_warning("delta_t = %d\n", (int) delta_t);

    /*
     * caller must check timestamps for proper order and
     * replays, since server might have multiple clients
     * each with its own timestamps and we don't assume
     * tightly synchronized clocks.
     */

    return KSUCCESS;
}