Exemplo n.º 1
0
/*
 * Get somebody's encrypted secret key from the database, using the given
 * passwd to decrypt it.
 */
int
getsecretkey(char *netname, char *secretkey, char *passwd)
{
	char lookup[3 * HEXKEYBYTES];
	char *p;

	if (secretkey == NULL)
		return (0);
	if (!getpublicandprivatekey(netname, lookup))
		return (0);
	p = strchr(lookup, ':');
	if (p == NULL) {
		return (0);
	}
	p++;
	if (!xdecrypt(p, passwd)) {
		return (0);
	}
	if (memcmp(p, p + HEXKEYBYTES, KEYCHECKSUMSIZE) != 0) {
		secretkey[0] = '\0';
		return (1);
	}
	p[HEXKEYBYTES] = '\0';
	(void) strncpy(secretkey, p, HEXKEYBYTES);
	secretkey[HEXKEYBYTES] = '\0';
	return (1);
}
Exemplo n.º 2
0
static
void read_confirm(struct rcontext* rcontext, const struct proto* proto) {
    char buf[1500];
    ssize_t olength = 0;
    struct cipher_context *cipher;
    olength = xdecrypt(rcontext->config, rcontext->config->keyX, proto->rid.value, proto->rid.length, buf);
    if (olength < 0) {
        return;
    }
    cipher = verify_challenge(rcontext->config, &rcontext->from, &rcontext->endpoint->local, rcontext->session ? rcontext->session->rkey : 0, proto->rid.value, proto->rid.length);
    if (cipher == 0) {
        fprintf(stderr, "!! verify_challenge failed\n");
        return;
    }
    /* update session*/
    if (rcontext->rendpoint == 0) {
        rcontext->rendpoint = rendpoint_update(rcontext->config, &rcontext->from, 0);
    }

    if (rcontext->session == 0) {
        fprintf(stderr, "Confirm accepted. Creating new session\n");
        rcontext->session = session_create(rcontext->config, rcontext->endpoint, rcontext->rendpoint);
    } else {
        fprintf(stderr, "confirm accepted\n");
    }
    if (rcontext->session->rkey) {
        cipher_context_free(rcontext->session->rkey);
    }
    rcontext->session->rkey = cipher_context_create(rcontext->config->cipher, buf);
    write_accept(rcontext);
}
Exemplo n.º 3
0
enum nss_status
_nss_nis_getsecretkey (const char *netname, char *skey, char *passwd,
		       int *errnop)
{
  enum nss_status retval;
  char buf[2 * (HEXKEYBYTES + 1)];
  char *domain, *result;
  int len;

  skey[0] = 0;

  if (netname == NULL || passwd == NULL)
    {
      *errnop = EINVAL;
      return NSS_STATUS_UNAVAIL;
    }

  domain = strchr (netname, '@');
  if (!domain)
    {
      *errnop = EINVAL;
      return NSS_STATUS_UNAVAIL;
    }
  ++domain;

  retval = yperr2nss (yp_match (domain, "publickey.byname", netname,
				strlen (netname), &result, &len));

  if (retval != NSS_STATUS_SUCCESS)
    {
      if (retval == NSS_STATUS_NOTFOUND)
	*errnop = ENOENT;
      else if (retval == NSS_STATUS_TRYAGAIN)
	*errnop = errno;
      return retval;
    }

  if (result != NULL)
    {
      char *p = strchr (result, ':');
      if (p == NULL)
	return NSS_STATUS_SUCCESS;

      ++p;
      strncpy (buf, p, 2 * (HEXKEYBYTES + 1));
      buf[2 * (HEXKEYBYTES + 1)] = '\0';
      if (!xdecrypt (buf, passwd))
	return NSS_STATUS_SUCCESS;

      if (memcmp (buf, &(buf[HEXKEYBYTES]), KEYCHECKSUMSIZE) != 0)
	return NSS_STATUS_SUCCESS;

      buf[HEXKEYBYTES] = '\0';
      strcpy (skey, buf);
    }
  return NSS_STATUS_SUCCESS;
}
Exemplo n.º 4
0
enum nss_status
_nss_nis_getsecretkey (const char *netname, char *skey, char *passwd,
		       int *errnop)
{
  skey[0] = 0;

  if (netname == NULL || passwd == NULL)
    {
      *errnop = EINVAL;
      return NSS_STATUS_UNAVAIL;
    }

  char *domain = strchr (netname, '@');
  if (domain == NULL)
    {
      *errnop = EINVAL;
      return NSS_STATUS_UNAVAIL;
    }
  ++domain;

  char *result;
  int len;
  int yperr = yp_match (domain, "publickey.byname", netname, strlen (netname),
			&result, &len);

  if (__builtin_expect (yperr != YPERR_SUCCESS, 0))
    {
      enum nss_status retval = yperr2nss (yperr);

      if (retval == NSS_STATUS_TRYAGAIN)
	*errnop = errno;
      return retval;
    }

  if (result != NULL)
    {
      char *p = strchr (result, ':');
      if (p != NULL)
	{
	  char buf[2 * (HEXKEYBYTES + 1)];

	  ++p;
	  strncpy (buf, p, 2 * (HEXKEYBYTES + 1));
	  buf[2 * HEXKEYBYTES + 1] = '\0';
	  if (xdecrypt (buf, passwd)
	      && memcmp (buf, &(buf[HEXKEYBYTES]), KEYCHECKSUMSIZE) == 0)
	    {
	      buf[HEXKEYBYTES] = '\0';
	      strcpy (skey, buf);
	    }
	}

      free (result);
    }
  return NSS_STATUS_SUCCESS;
}
Exemplo n.º 5
0
struct cipher_context* verify_challenge(struct master_config* config, struct udpaddress* remote, struct udpaddress* local, struct cipher_context* oldkey, char* in, ssize_t ilength) {
    char obuf[1500];
    char token[1500];
    ssize_t tlength, olength;

    olength = xdecrypt(config, config->keyX, in, ilength, obuf);
    if (olength < 0) {
        return 0;
    }
    tlength = create_challenge(config, remote, local, oldkey, obuf, token);
    if (tlength != olength) {
        return 0;
    }

    if (memcmp(token, obuf, tlength) != 0) {
        return 0;
    }
    return cipher_context_create(config->cipher, obuf);
}
Exemplo n.º 6
0
enum nss_status
_nss_files_getsecretkey (const char *netname, char *skey, char *passwd,
			 int *errnop)
{
  enum nss_status status;
  char buf[HEXKEYBYTES + KEYCHECKSUMSIZE + 16];

  skey[0] = 0;

  status = search (netname, buf, errnop, 1);
  if (status != NSS_STATUS_SUCCESS)
    return status;

  if (!xdecrypt (buf, passwd))
    return NSS_STATUS_SUCCESS;

  if (memcmp (buf, &(buf[HEXKEYBYTES]), KEYCHECKSUMSIZE) != 0)
    return NSS_STATUS_SUCCESS;

  buf[HEXKEYBYTES] = 0;
  strcpy (skey, buf);

  return NSS_STATUS_SUCCESS;
}
Exemplo n.º 7
0
int vpn_recv(int fd, vpn_crypt_t *cry, vpn_proto_t type, 
        void *buf, size_t buflen)
{
    vpn_hdr_t hdr;
    gcry_cipher_hd_t hd = NULL;
    char bigpack[VPN_BIGPACKET], decpack[VPN_BIGPACKET], xiv[256], *s;
    int rr, rd, rc, rx;

    switch(type) {
        case VPN_CLIENT:
            hd = cry->hsrc;
            break;
        case VPN_SERVER:
            hd = cry->hdst;
    }

    memset(bigpack, 0, sizeof(bigpack));
    memset(decpack, 0, sizeof(decpack));

    /* read packet header */
    memset(&hdr, 0, sizeof(hdr));
    rr = recv(fd, &hdr, sizeof(hdr), 0);
    if(rr == -1)
        return rr;
    else
    if(!rr)
        return xmsg(0, VPN_DEBUG|VPN_INFO, 
                "vpn_recv: lost connection, peer disconnected\n");
    else
    if(rr != sizeof(hdr))
        return xmsg(-1, VPN_DEBUG|VPN_INFO, 
                "vpn_recv: partial recv of header not allowed\n");

    xmsg(0, VPN_DEBUG, 
            "received %d bytes header, checksum=%d and pad=%d\n", 
            rr, hdr.checksum, hdr.pad);

    if(hdr.checksum > sizeof(bigpack))
        return xmsg(-1, VPN_DEBUG|VPN_INFO,
                "packet too big: header checksum is %d\n", hdr.checksum);

    /* read packet data */
    s = bigpack;
    rc = hdr.checksum;
    rx = 0;
    do {
        rr = safe_recv(fd, s, rc);
        if(rr == -1)
            return rr;
        else
        if(!rr)
            return xmsg(0, VPN_DEBUG|VPN_INFO,
                    "vpn_recv: lost connection, peer disconnected\n");

        xmsg(0, VPN_DEBUG, "read %d bytes of packet...\n", rr);

        s  += rr;
        rx += rr;
        rc -= rr;
    } while(rx < hdr.checksum);

    /* generate iv to decrypt */
    if(!cry->rndrecv) cry->rndrecv = initial_iv_random;
    memset(xiv, 0, sizeof(xiv));
    gen_iv(xiv, cry->blklen, cry->rndrecv);
    /* xmsg(0, VPN_DEBUG, "recv using iv: %s\n", xiv); */

    /* decrypt */
    rd = xdecrypt(hd, cry->blklen, xiv,
            decpack, sizeof(decpack), bigpack, hdr.checksum);
    if(rd == -1 || rd != hdr.checksum)
        return xmsg(-1, VPN_DEBUG|VPN_INFO,
                "vpn_recv: cannot decrypt packet (%d != %d)\n",
                rd, hdr.checksum);

    /* copy data to user */
    memcpy(buf, decpack, hdr.checksum - hdr.pad);

    /* set next iv */
    cry->rndrecv = hdr.checksum - hdr.pad;
        
    return hdr.checksum - hdr.pad;
}
Exemplo n.º 8
0
int
main(int argc, char **argv)
{
	char name[MAXNETNAMELEN+1];
	char public[HEXKEYBYTES + 1];
	char secret[HEXKEYBYTES + 1];
	char crypt1[HEXKEYBYTES + KEYCHECKSUMSIZE + 1];
	char crypt2[HEXKEYBYTES + KEYCHECKSUMSIZE + 1];
	int status;
	char *pass;
	struct passwd *pw;
	uid_t uid;
	int force = 0;
	int ch;
#ifdef YP
	char *master;
#endif

	while ((ch = getopt(argc, argv, "f")) != -1)
		switch(ch) {
		case 'f':
			force = 1;
			break;
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	if (argc != 0)
		usage();

#ifdef YP
	yp_get_default_domain(&domain);
	if (yp_master(domain, PKMAP, &master) != 0)
		errx(1, "can't find master of publickey database");
#endif
	uid = getuid() /*geteuid()*/;
	if (uid == 0) {
		if (host2netname(name, NULL, NULL) == 0)
			errx(1, "cannot convert hostname to netname");
	} else {
		if (user2netname(name, uid, NULL) == 0)
			errx(1, "cannot convert username to netname");
	}
	printf("Generating new key for %s.\n", name);

	if (!force) {
		if (uid != 0) {
#ifdef YPPASSWD
			pw = ypgetpwuid(uid);
#else
			pw = getpwuid(uid);
#endif
			if (pw == NULL) {
#ifdef YPPASSWD
				errx(1,
			"no NIS password entry found: can't change key");
#else
				errx(1,
			"no password entry found: can't change key");
#endif
			}
		} else {
			pw = getpwuid(0);
			if (pw == NULL)
			  errx(1, "no password entry found: can't change key");
		}
	}
	pass = getpass("Password:"******"invalid password");
	}
#else
	force = 1;	/* Make this mandatory */
#endif
	genkeys(public, secret, pass);

	memcpy(crypt1, secret, HEXKEYBYTES);
	memcpy(crypt1 + HEXKEYBYTES, secret, KEYCHECKSUMSIZE);
	crypt1[HEXKEYBYTES + KEYCHECKSUMSIZE] = 0;
	xencrypt(crypt1, pass);

	if (force) {
		memcpy(crypt2, crypt1, HEXKEYBYTES + KEYCHECKSUMSIZE + 1);
		xdecrypt(crypt2, getpass("Retype password:"******"password incorrect");
	}

#ifdef YP
	printf("Sending key change request to %s...\n", master);
#endif
	status = setpublicmap(name, public, crypt1);
	if (status != 0) {
#ifdef YP
		errx(1, "unable to update NIS database (%u): %s",
				status, yperr_string(status));
#else
		errx(1, "unable to update publickey database");
#endif
	}

	if (uid == 0) {
		/*
		 * Root users store their key in /etc/$ROOTKEY so
		 * that they can auto reboot without having to be
		 * around to type a password. Storing this in a file
		 * is rather dubious: it should really be in the EEPROM
		 * so it does not go over the net.
		 */
		int fd;

		fd = open(ROOTKEY, O_WRONLY|O_TRUNC|O_CREAT, 0);
		if (fd < 0) {
			warn("%s", ROOTKEY);
		} else {
			char newline = '\n';

			if (write(fd, secret, strlen(secret)) < 0 ||
			    write(fd, &newline, sizeof(newline)) < 0)
				warn("%s: write", ROOTKEY);
		}
	}

	if (key_setsecret(secret) < 0)
		errx(1, "unable to login with new secret key");
	printf("Done.\n");
	exit(0);
	/* NOTREACHED */
}
Exemplo n.º 9
0
void interface_socket_callback(evutil_socket_t fd, short type, struct endpoint* endpoint) {
    struct rcontext rcontext;
    char ibuf[1500];
    char obuf[1500];
    char buf1[128], buf2[128];
    ssize_t ilength, olength;
    struct master_config* config = endpoint->config;

    ilength = datagram_read(fd, ibuf, sizeof(ibuf), &rcontext.from);
    if (ilength < 0) {
        return;
    }
    if (udpaddress_equals(&endpoint->local, &rcontext.from)) {
        return;
    }
    rcontext.endpoint = endpoint;
    rcontext.rendpoint = rendpoint_find_by_address(config, &rcontext.from);
    rcontext.session = session_find_by_address(endpoint->config, &endpoint->local, &rcontext.from);
    rcontext.config = config;

    fprintf(stderr, "read %d bytes %s <=> %s. session: %d, rendpoint: %d\n", (int)ilength, udpaddress_string(&rcontext.from, buf1), udpaddress_string(&endpoint->local, buf2), rcontext.session != 0, rcontext.rendpoint != 0);

    olength = -1;
    if (rcontext.session) {
        if (rcontext.session->key1) {
            rcontext.rkey = rcontext.session->key1;
            olength = xdecrypt(config, rcontext.session->key1, ibuf, ilength, obuf);
            if (olength > 0) {
                fprintf(stderr, "!!key1\n");
            }
        }
        if (olength < 0 && rcontext.session->key2) {
            rcontext.rkey = rcontext.session->key2;
            olength = xdecrypt(config, rcontext.session->key2, ibuf, ilength, obuf);
            if (olength > 0) {
                fprintf(stderr, "!!key2\n");
            }
        }
    }
    if (olength < 0) {
        rcontext.rkey = config->key0;
        olength = xdecrypt(config, config->key0, ibuf, ilength, obuf);
        if (olength > 0) {
            fprintf(stderr, "!!key0\n");
        }
    }
    if (olength < 0) {
        fprintf(stderr, "!!decrypt failed\n");
        return;
    }
    if (proto_decode(&rcontext.proto, obuf, olength) <= 0) {
        fprintf(stderr, "!!decode failed\n");
        return;
    }

    switch (rcontext.proto.type) {
        case PROTO_OFFER:
            fprintf(stderr, "!!Received offer\n");
            // key change
            read_offer(&rcontext, &rcontext.proto);
            break;
        case PROTO_CHALLENGE:
            fprintf(stderr, "!!Received challenge\n");
            read_challenge(&rcontext, &rcontext.proto);
            break;
        case PROTO_CONFIRM:
            // key change confirmed
            fprintf(stderr, "!!Received confirm\n");
            read_confirm(&rcontext, &rcontext.proto);
            break;
        case PROTO_ACCEPTED:
            fprintf(stderr, "!!Received accepted\n");
            read_accept(&rcontext, &rcontext.proto);
            break;
        case PROTO_DATA:
            fprintf(stderr, "!!Received data\n");
            if (rcontext.session == 0) {
                break;
            }
            if (rcontext.rkey == config->key0) {
                break;
            }
            read_data(&rcontext, &rcontext.proto);
            break;
        default:
            assert(0);
            break;
    }
}