Skip to content
Permalink
Browse files Browse the repository at this point in the history
Merge pull request #20 from eyalitki/master
2nd round security fixes from eyalitki
  • Loading branch information
haakonnessjoen committed Aug 30, 2016
2 parents b9cede3 + 9d946fa commit b69d117
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 16 deletions.
21 changes: 14 additions & 7 deletions mactelnet.c
Expand Up @@ -96,7 +96,7 @@ static char autologin_path[255];

static int keepalive_counter = 0;

static unsigned char pass_salt[17];
static unsigned char pass_salt[16];
static char username[MT_MNDP_MAX_STRING_SIZE];
static char password[MT_MNDP_MAX_STRING_SIZE];
static char nonpriv_username[MT_MNDP_MAX_STRING_SIZE];
Expand Down Expand Up @@ -212,23 +212,26 @@ static void send_auth(char *username, char *password) {
char *terminal = getenv("TERM");
char md5data[100];
unsigned char md5sum[17];
int plen;
int plen, act_pass_len;
md5_state_t state;

#if defined(__linux__) && defined(_POSIX_MEMLOCK_RANGE)
mlock(md5data, sizeof(md5data));
mlock(md5sum, sizeof(md5data));
#endif

/* calculate the actual password's length */
act_pass_len = strnlen(password, 82);

/* Concat string of 0 + password + pass_salt */
md5data[0] = 0;
strncpy(md5data + 1, password, 82);
md5data[83] = '\0';
memcpy(md5data + 1 + strlen(password), pass_salt, 16);
memcpy(md5data + 1, password, act_pass_len);
/* in case that password is long, calculate only using the used-up parts */
memcpy(md5data + 1 + act_pass_len, pass_salt, 16);

/* Generate md5 sum of md5data with a leading 0 */
md5_init(&state);
md5_append(&state, (const md5_byte_t *)md5data, strlen(password) + 17);
md5_append(&state, (const md5_byte_t *)md5data, 1 + act_pass_len + 16);
md5_finish(&state, (md5_byte_t *)md5sum + 1);
md5sum[0] = 0;

Expand Down Expand Up @@ -312,7 +315,11 @@ static int handle_packet(unsigned char *data, int data_len) {

/* If we receive pass_salt, transmit auth data back */
if (cpkt.cptype == MT_CPTYPE_PASSSALT) {
memcpy(pass_salt, cpkt.data, cpkt.length);
/* check validity, server sends exactly 16 bytes */
if (cpkt.length != 16) {
fprintf(stderr, _("Invalid salt length: %d (instead of 16) received from server %s\n"), cpkt.length, ether_ntoa((struct ether_addr *)dstmac));
}
memcpy(pass_salt, cpkt.data, 16);
send_auth(username, password);
}

Expand Down
15 changes: 10 additions & 5 deletions mactelnetd.c
Expand Up @@ -407,6 +407,7 @@ static void user_login(struct mt_connection *curconn, struct mt_mactelnet_hdr *p
char md5data[100];
struct mt_credentials *user;
char *slavename;
int act_pass_len;

/* Reparse user file before each login */
read_userfile();
Expand All @@ -421,14 +422,18 @@ static void user_login(struct mt_connection *curconn, struct mt_mactelnet_hdr *p
}
#endif

/* calculate the password's actual length */
act_pass_len = strlen(user->password);
act_pass_len = act_pass_len <= 82 ? act_pass_len : 82;

/* Concat string of 0 + password + pass_salt */
md5data[0] = 0;
strncpy(md5data + 1, user->password, 82);
memcpy(md5data + 1 + strlen(user->password), curconn->pass_salt, 16);
memcpy(md5data + 1, user->password, act_pass_len);
memcpy(md5data + 1 + act_pass_len, curconn->pass_salt, 16);

/* Generate md5 sum of md5data with a leading 0 */
md5_init(&state);
md5_append(&state, (const md5_byte_t *)md5data, strlen(user->password) + 17);
md5_append(&state, (const md5_byte_t *)md5data, 1 + act_pass_len + 16);
md5_finish(&state, (md5_byte_t *)md5sum + 1);
md5sum[0] = 0;

Expand Down Expand Up @@ -635,7 +640,7 @@ static void handle_data_packet(struct mt_connection *curconn, struct mt_mactelne
memcpy(curconn->terminal_type, cpkt.data, act_size = (cpkt.length > 30 - 1 ? 30 - 1 : cpkt.length));
curconn->terminal_type[act_size] = 0;

} else if (cpkt.cptype == MT_CPTYPE_PASSWORD) {
} else if (cpkt.cptype == MT_CPTYPE_PASSWORD && cpkt.length == 17) {

#if defined(__linux__) && defined(_POSIX_MEMLOCK_RANGE)
mlock(curconn->trypassword, 17);
Expand All @@ -651,7 +656,7 @@ static void handle_data_packet(struct mt_connection *curconn, struct mt_mactelne
}

} else {
syslog(LOG_WARNING, _("(%d) Unhandeled control packet type: %d"), curconn->seskey, cpkt.cptype);
syslog(LOG_WARNING, _("(%d) Unhandeled control packet type: %d, length: %d"), curconn->seskey, cpkt.cptype, cpkt.length);
}

/* Parse next control packet */
Expand Down
10 changes: 6 additions & 4 deletions protocol.c
Expand Up @@ -84,8 +84,9 @@ int add_control_packet(struct mt_packet *packet, enum mt_cptype cptype, void *cp
unsigned char *data = packet->data + packet->size;
unsigned int act_size = data_len + (cptype == MT_CPTYPE_PLAINDATA ? 0 : MT_CPHEADER_LEN);

/* Something is really wrong. Packets should never become over 1500 bytes */
if (packet->size + act_size > MT_PACKET_LEN) {
/* Something is really wrong. Packets should never become over 1500 bytes,
perform an Integer-Overflow safe check */
if (act_size > MT_PACKET_LEN - packet->size) {
fprintf(stderr, _("add_control_packet: ERROR, too large packet. Exceeds %d bytes\n"), MT_PACKET_LEN);
return -1;
//exit(1);
Expand Down Expand Up @@ -149,7 +150,8 @@ int init_pongpacket(struct mt_packet *packet, unsigned char *srcmac, unsigned ch
}

int add_packetdata(struct mt_packet *packet, unsigned char *data, unsigned short length) {
if (packet->size + length > MT_PACKET_LEN) {
/* Integer-Overflow safe check */
if (length > MT_PACKET_LEN - packet->size) {
fprintf(stderr, _("add_control_packet: ERROR, too large packet. Exceeds %d bytes\n"), MT_PACKET_LEN);
return -1;
}
Expand Down Expand Up @@ -272,7 +274,7 @@ int mndp_add_attribute(struct mt_packet *packet, enum mt_mndp_attrtype attrtype,
unsigned short len = data_len;

/* Something is really wrong. Packets should never become over 1500 bytes */
if (packet->size + 4 + data_len > MT_PACKET_LEN) {
if (data_len > MT_PACKET_LEN - 4 - packet->size) {
fprintf(stderr, _("mndp_add_attribute: ERROR, too large packet. Exceeds %d bytes\n"), MT_PACKET_LEN);
return -1;
}
Expand Down

0 comments on commit b69d117

Please sign in to comment.