/* * Generate the MD5 hash for a VTP Summary-Advert packet */ int8_t vtp_generate_md5(char *secret, u_int32_t updater, u_int32_t revision, char *domain, u_int8_t dom_len, u_int8_t *vlans, u_int16_t vlans_len, u_int8_t *md5, u_int8_t version) { u_int8_t *data, md5_secret[16]; struct vtp_summary *vtp_summ; /* Space for the data (MD5+SUMM_ADVERT+VLANS+MD5)...*/ if ( (data = calloc(1, (16+sizeof(struct vtp_summary)+vlans_len+16))) == NULL) { thread_error("vtp_generate_md5 calloc()",errno); return -1; } /* Do MD5 secret...*/ if (secret) md5_sum(data, strlen(secret), md5_secret); vtp_summ = (struct vtp_summary *)(data+16); write_log(0,"Se calcula MD5 con version=%d\n",version); vtp_summ->version = version; vtp_summ->code = 0x01; if (dom_len > VTP_DOMAIN_SIZE) { vtp_summ->dom_len = VTP_DOMAIN_SIZE; memcpy(vtp_summ->domain,domain,VTP_DOMAIN_SIZE); } else { vtp_summ->dom_len = dom_len; memcpy(vtp_summ->domain,domain,dom_len); } vtp_summ->updater = htonl(updater); vtp_summ->revision = htonl(revision); if (vlans_len) memcpy((void *)(vtp_summ+1),vlans,vlans_len); if (secret) memcpy((void *)(data+16+sizeof(struct vtp_summary)+vlans_len),md5_secret,16); md5_sum(data, (32+sizeof(struct vtp_summary)+vlans_len), md5); free(data); return 0; }
int db_prepare(sqlite3 **db){ char query[DIM]; char name[DIM] = {0}; char password[DIM] = {0}; char aux1[DIM] = {0}; char pass[MD5_DIGEST_LENGTH]; int nbytes = 0; sprintf(query, "CREATE TABLE IF NOT EXISTS users(userID INTEGER PRIMARY KEY AUTOINCREMENT, user TEXT, password TEXT, ROL INTEGER);"); if(db_exec(db, query, CREATE_TABLE) < 0){ sqlite3_close(*db); PDEBUG("DB: Error al crear la tabla\n"); return -1; } printf("Nombre del administrador: \n"); nbytes = read(0, &query, DIM); query[nbytes - 1] = '\0'; // eliminamos el intro addslahses(query, DIM, name); // escapamos las comillas simples printf("Contraseña del administrador: \n"); echo_off(); bzero(query, DIM); nbytes = read(0, &query, DIM); query[nbytes - 1] = '\0'; // eliminamos el intro echo_on(); // creamos la suma PDEBUG("DB: Caluclando la suma MD5\n"); MD5((unsigned char*) query, DIM, (unsigned char*)pass); // obtenemos la suma MD5 en caracteres ascii md5_sum((unsigned char*) pass, MD5_DIGEST_LENGTH, DIM, aux1); addslahses((char *)aux1, DIM, password); //creamos la query PDEBUG("DB: Insertando al administrador del sistema\n"); sprintf(query, "INSERT INTO users (user, password, rol) VALUES ('%s', '%s', %i);", name, password, ADMIN); if(db_exec(db, query, INSERT) <0){ sqlite3_close(*db); PDEBUG("DB: Error al insertar el usuario administrador\n"); return -1; } PDEBUG("DB: Creando la tabla del log\n"); sprintf(query, "CREATE TABLE IF NOT EXISTS log(postID INTEGER PRIMARY KEY AUTOINCREMENT, author TEXT, text TEXT, time LONG);"); if(db_exec(db, query, CREATE_TABLE) < 0){ sqlite3_close(*db); PDEBUG("DB: Error al crear la tabla\n"); return -1; } return 0; }
char * md5sum (char *str) { unsigned char sum[MD5_SUM_SIZE]; char md5[MD5_SIZE]; int i; if (!str) return NULL; md5_sum (sum, (const uint8_t *) str, strlen(str)); memset (md5, '\0', MD5_SIZE); for (i = 0; i < MD5_SUM_SIZE; i++) { char tmp[3]; sprintf (tmp, "%02x", sum[i]); strcat (md5, tmp); } return strdup (md5); }
int db_addUser(char* name, char* password, int rol, sqlite3** db){ char query[DIM]; char aux[DIM]; // creamos la suma PDEBUG("DB: Caluclando la suma MD5\n"); MD5((unsigned char*) password, DIM, (unsigned char*)query); // obtenemos la suma MD5 en caracteres ascii md5_sum((unsigned char*) query, MD5_DIGEST_LENGTH, DIM, aux); addslahses((char *)aux, DIM, password); strcpy(query, name); addslahses((char *)query, DIM, aux); PDEBUG("DB: ¿Existe ya el usuario?\n"); sprintf(query, "SELECT * FROM users WHERE user='******';", aux); if(db_exec(db, query, COUNT_ROWS) <0){ sqlite3_close(*db); PDEBUG("DB: Error al insertar el usuario administrador\n"); return -1; } if(numRows > 0){ return 1; } PDEBUG("DB: Insertando el usuario\n"); sprintf(query, "INSERT INTO users (user, password, rol) VALUES ('%s', '%s', %i);", aux, password, rol); if(db_exec(db, query, INSERT) <0){ sqlite3_close(*db); PDEBUG("DB: Error al insertar el usuario administrador\n"); return -1; } return 0; }
int db_checkUser(char* name, char* password, sqlite3** db){ char query[DIM]; char aux[DIM]; // creamos la suma PDEBUG("DB: Caluclando la suma MD5\n"); MD5((unsigned char*) password, DIM, (unsigned char*)query); // obtenemos la suma MD5 en caracteres ascii md5_sum((unsigned char*) query, MD5_DIGEST_LENGTH, DIM, aux); addslahses((char *)aux, DIM, password); strcpy(query, name); addslahses((char *)query, DIM, aux); sprintf(query, "SELECT rol FROM users WHERE user='******' AND password='******';", aux, password); rol = 0; if(db_exec(db, query, GET_ROL) < 0){ sqlite3_close(*db); PDEBUG("DB: Error al comprobar si el usuario existe\n"); return -1; } return rol; }
static int kindle_info_main(int argc, char *argv[]) { char *serial_no; char md5[MD5_HASH_LENGTH]; char device_code[4] = {'\0'}; Device device; FILE *temp; unsigned int i; // Skip command argv++; argc--; if(argc < 1) { fprintf(stderr, "Missing argument. You must pass a serial number.\n"); return -1; } serial_no = argv[0]; temp = tmpfile(); if(strlen(serial_no) != SERIAL_NO_LENGTH) { fprintf(stderr, "Serial number must be 16 digits long (no spaces). Example: %s\n", "B0NNXXXXXXXXXXXX"); return -1; } for(i = 0; i < SERIAL_NO_LENGTH; i++) { if(islower((int)serial_no[i])) { serial_no[i] = (char)toupper((int)serial_no[i]); } } // Find root password if(fprintf(temp, "%s\n", serial_no) < SERIAL_NO_LENGTH) { fprintf(stderr, "Cannot write serial to temporary file: %s.\n", strerror(errno)); fclose(temp); return -1; } rewind(temp); if(md5_sum(temp, md5) < 0) { fprintf(stderr, "Cannot calculate MD5 of serial number.\n"); fclose(temp); return -1; } snprintf(device_code, 3, "%.*s", 2, &serial_no[2]); device = (Device)strtoul(device_code, NULL, 16); // Handle the new device ID position, since the PW3 if(strcmp(convert_device_id(device), "Unknown") == 0) { snprintf(device_code, 4, "%.*s", 3, &serial_no[3]); device = (Device)strtoul(device_code, NULL, 32); if(strcmp(convert_device_id(device), "Unknown") == 0) { fprintf(stderr, "Unknown device!\n"); fclose(temp); return -1; } else { fprintf(stderr, "Device uses the new device ID scheme\n"); } } // Handle the Wario (>= PW2) passwords while we're at it... Thanks to npoland for this one ;). // NOTE: Remember to check if this is still sane w/ kindle_model_sort.py when new stuff comes out! if(device == KindleVoyageWiFi || device == KindlePaperWhite2WiFi4GBInternational || device >= KindleVoyageUnknown_0x2A) { fprintf(stderr, "Platform is Wario or newer\n"); fprintf(stderr, "Root PW %s%.*s\nRecovery PW %s%.*s\n", "fiona", 3, &md5[13], "fiona", 4, &md5[13]); } else { fprintf(stderr, "Platform is pre Wario\n"); fprintf(stderr, "Root PW %s%.*s\nRecovery PW %s%.*s\n", "fiona", 3, &md5[7], "fiona", 4, &md5[7]); } // Default root passwords are DES hashed, so we only care about the first 8 chars. On the other hand, // the recovery MMC export option expects a 9 chars password, so, provide both... fclose(temp); return 0; }
/* Returns the length of the file received, or 0 on error: */ int ymodem_receive(char *buf, unsigned int length) { unsigned char packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD]; int packet_length, i, file_done, session_done, crc_tries, crc_nak, use_crc; unsigned int packets_received, errors, timeout, first_try = 1; char file_name[FILE_NAME_LENGTH], file_size[FILE_SIZE_LENGTH], *file_ptr; char *buf_ptr; unsigned long size = 0; #ifdef CONFIG_MD5 unsigned int sum[MD5_SUM_WORDS]; #endif if(crc16_init() < 0){ putstr("Unable to generate CRC16 lookup table\r\n"); return 0; } putstr("ready for YMODEM transfer...\r\n"); /* Give the user time to frantically type in the file name: */ timeout = INITIAL_TIMEOUT; for(session_done = 0, errors = 0; ; ){ crc_tries = crc_nak = use_crc = 1; if(!first_try) putc(CRC); first_try = 0; for(packets_received = 0, file_done = 0, buf_ptr = buf; ; ){ switch(receive_packet(packet_data, &packet_length, use_crc, timeout)){ case 0: errors = 0; switch(packet_length){ case -1: /* abort */ putc(ACK); return 0; case 0: /* end of transmission */ putc(ACK); /* Should add some sort of sanity check on the number of * packets received and the advertised file length. */ file_done = 1; break; default: /* normal packet */ if((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff)){ putc(NAK); } else { if(packets_received == 0){ /* The spec suggests that the whole data section should * be zeroed, but I don't think all senders do this. If * we have a NULL filename and the first few digits of * the file length are zero, we'll call it empty. */ for(i = PACKET_HEADER; i < PACKET_HEADER + 4; ++i) if(packet_data[i] != 0) break; if(i < PACKET_HEADER + 4){ /* filename packet has data */ for(file_ptr = packet_data + PACKET_HEADER, i = 0; *file_ptr && i < FILE_NAME_LENGTH;) file_name[i++] = *file_ptr++; file_name[i++] = '\0'; for(++file_ptr, i = 0; *file_ptr != ' ' && i < FILE_SIZE_LENGTH;) file_size[i++] = *file_ptr++; file_size[i++] = '\0'; size = strtoul(file_size, NULL, 0); if(size > length){ putc(CAN); putc(CAN); delay_seconds(3); putstr("Receive buffer too small ("); putHexInt32(length); putLabeledWord(") to accept file size ", size); return 0; } putc(ACK); putc(crc_nak ? CRC : NAK); crc_nak = 0; } else { /* filename packet is empty; end session */ putc(ACK); file_done = 1; session_done = 1; break; } } else { /* This shouldn't happen, but we check anyway in case the * sender lied in its filename packet: */ if((buf_ptr + packet_length) - buf > length){ putc(CAN); putc(CAN); delay_seconds(3); putLabeledWord("Sender exceeded size of receive buffer: ", length); return 0; } memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length); buf_ptr += packet_length; putc(ACK); } ++packets_received; } /* sequence number ok */ } break; default: if(++errors >= ((packets_received == 0 ? MAX_CRC_TRIES : 0) + MAX_ERRORS)){ putc(CAN); putc(CAN); delay_seconds(1); putstr("Too many errors during receive; giving up.\r\n"); return 0; } if(packets_received == 0){ if(crc_tries < MAX_CRC_TRIES) { ++crc_tries; timeout = CRC_TIMEOUT; } else { crc_nak = use_crc = 0; timeout = NAK_TIMEOUT; } } putc(crc_nak ? CRC : NAK); } if(file_done) break; } /* receive packets */ if(session_done) break; } /* receive files */ #ifdef CONFIG_MD5 /* Give sender time to exit so that the subsequent MD5 display will be * visible on the user's terminal: */ delay_seconds(1); md5_sum(buf, size, sum); md5_display(sum); putstr(" "); putstr(file_name); putstr("\r\n"); #endif return size; }