void md5_loop(md5_ctx *ctx, const uint8_t *input, size_t len) { size_t gap, i; ctx->md5_n += len * 8; /* byte to bit */ gap = MD5_BUFLEN - ctx->md5_i; if (len >= gap) { memcpy((void *)(ctx->md5_buf + ctx->md5_i), (void *)input, gap); md5_calc(ctx->md5_buf, ctx); for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) { md5_calc((uint8_t *)(input + i), ctx); } ctx->md5_i = len - i; memcpy((void *)ctx->md5_buf, (void *)(input + i), ctx->md5_i); } else { memcpy((void *)(ctx->md5_buf + ctx->md5_i), (void *)input, len); ctx->md5_i += len; } }
void md5_pad(md5_ctxt *ctxt) { uint gap; /* Don't count up padding. Keep md5_n. */ gap = MD5_BUFLEN - ctxt->md5_i; if (gap > 8) { memcpy (ctxt->md5_buf + ctxt->md5_i, md5_paddat, gap - sizeof(ctxt->md5_n)); } else { /* including gap == 8 */ memcpy (ctxt->md5_buf + ctxt->md5_i, md5_paddat, gap); md5_calc (ctxt->md5_buf, ctxt); memcpy (ctxt->md5_buf, md5_paddat + gap, MD5_BUFLEN - sizeof(ctxt->md5_n)); } /* 8 byte word */ if (BYTE_ORDER == LITTLE_ENDIAN) memcpy (&ctxt->md5_buf[56], &ctxt->md5_n8[0], 8); else { ctxt->md5_buf[56] = ctxt->md5_n8[7]; ctxt->md5_buf[57] = ctxt->md5_n8[6]; ctxt->md5_buf[58] = ctxt->md5_n8[5]; ctxt->md5_buf[59] = ctxt->md5_n8[4]; ctxt->md5_buf[60] = ctxt->md5_n8[3]; ctxt->md5_buf[61] = ctxt->md5_n8[2]; ctxt->md5_buf[62] = ctxt->md5_n8[1]; ctxt->md5_buf[63] = ctxt->md5_n8[0]; } md5_calc(ctxt->md5_buf, ctxt); }
void md5_loop(md5_ctxt *ctxt, const uint8 *input, unsigned len) { unsigned int gap, i; ctxt->md5_n += len * 8; /* byte to bit */ gap = MD5_BUFLEN - ctxt->md5_i; if (len >= gap) { memmove(ctxt->md5_buf + ctxt->md5_i, input, gap); md5_calc(ctxt->md5_buf, ctxt); for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) md5_calc((uint8 *) (input + i), ctxt); ctxt->md5_i = len - i; memmove(ctxt->md5_buf, input + i, ctxt->md5_i); } else { memmove(ctxt->md5_buf + ctxt->md5_i, input, len); ctxt->md5_i += len; } }
int smpd_hash(char *input, int input_length, char *output, int output_length) { /*int i;*/ unsigned char hash[MD5_DIGEST_LENGTH]; smpd_enter_fn(FCNAME); if (output_length < (MD5_DIGEST_LENGTH * 2 + 1)) { smpd_exit_fn(FCNAME); return SMPD_FAIL; } #ifdef HAVE_MD5_CALC md5_calc(hash, (unsigned char *)input, (unsigned int)input_length); #else MD5(input, input_length, hash); #endif /* for (i=0; i<MD5_DIGEST_LENGTH; i++) { sprintf(output, "%02x", hash[i]); output += 2; } */ sprintf(output, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", hash[0], hash[1], hash[2], hash[3], hash[4], hash[5], hash[6], hash[7], hash[8], hash[9], hash[10], hash[11], hash[12], hash[13], hash[14], hash[15]); smpd_exit_fn(FCNAME); return SMPD_SUCCESS; }
int main() { struct stat sbuf; char sdirect[1000] = "./"; DIR *dir_s; //printf("Please input the sourse direct path and name :"); //输入目录名 //scanf("%s",sdirect); //sdirect = "./"; dir_s=opendir(sdirect); if(dir_s==NULL) { printf("This directory don't exist !\n"); return 0; } if(stat(sdirect,&sbuf)!=0) { printf("Get status error !\n"); return 0; } clock_t start=clock();//开始计时 md5_calc(sdirect,0); //调用函数 clock_t finish=clock();//结束计时 //printf("------------------------------------------------------\n"); //printf("Calculation specified file MD5 Used when the %ld ms\n",(long)(finish-start)); //计算用时 //printf("Calculated the total %d file\n",count); //计算扫描文件数 printf ("Develop by iCoding.\n"); return 0; }
void md5_calc(char *dir, int depth) { DIR *dp; struct dirent *entry; struct stat statbuf; if((dp = opendir(dir)) == NULL) { fprintf(stderr,"cannot open directory: %s\n", dir); return; } chdir(dir); while((entry = readdir(dp)) != NULL) { lstat(entry->d_name,&statbuf); if(S_ISDIR(statbuf.st_mode)) { /* Found a directory, but ignore . and .. */ if(strcmp(".",entry->d_name) == 0 || strcmp("..",entry->d_name) == 0) continue; printf("%*s%s/\n",depth,"",entry->d_name); /* Recurse at a new indent level */ md5_calc(entry->d_name,depth+4); } else { //printf("%*s%s\n",depth,"",entry->d_name); if (!(fp=fopen(entry->d_name,"rb"))) {printf("Can not open %s this file!\n",entry->d_name);continue;} //以二进制打开文件 fseek(fp, 0, SEEK_END); //文件指针转到文件末尾 if((len=ftell(fp))==-1) {printf("Sorry! Can not calculate files which larger than 2 GB!\n");fclose(fp);continue;} //ftell函数返回long,最大为2GB,超出返回-1 rewind(fp); //文件指针复位到文件头 A=0x67452301,B=0xefcdab89,C=0x98badcfe,D=0x10325476; //初始化链接变量 flen[1]=len/0x20000000; //flen单位是bit len是文件长度 flen[0]=(len%0x20000000)*8; memset(x,0,64); //初始化x数组为0 fread(&x,4,16,fp); //以4字节为一组,读取16组数据 for(i=0;i<len/64;i++){ //循环运算直至文件结束 md5(); memset(x,0,64); fread(&x,4,16,fp); } ((char*)x)[len%64]=128; //文件结束补1,补0操作,128二进制即10000000 if(len%64>55) md5(),memset(x,0,64); memcpy(x+14,flen,8); //文件末尾加入原文件的bit长度 md5(); fclose(fp); printf("%08x%08x%08x%08x ",PP(A),PP(B),PP(C),PP(D)); //高低位逆反输出 printf("%s\n",entry->d_name); count++;//计算文件数量 } } chdir(".."); closedir(dp); }
void md5_loop(md5_ctxt *ctxt, const void *vinput, uint len) { uint gap, i; const uint8_t *input = vinput; ctxt->md5_n += len * 8; /* byte to bit */ gap = MD5_BUFLEN - ctxt->md5_i; if (len >= gap) { memcpy (ctxt->md5_buf + ctxt->md5_i, input, gap); md5_calc(ctxt->md5_buf, ctxt); for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) { md5_calc((input + i), ctxt); } ctxt->md5_i = len - i; memcpy (ctxt->md5_buf, (input + i), ctxt->md5_i); } else { memcpy (ctxt->md5_buf + ctxt->md5_i, input, len); ctxt->md5_i += len; } }
void md5_pad(md5_ctxt *ctxt) { unsigned int gap; /* Don't count up padding. Keep md5_n. */ gap = MD5_BUFLEN - ctxt->md5_i; if (gap > 8) { memmove(ctxt->md5_buf + ctxt->md5_i, md5_paddat, gap - sizeof(ctxt->md5_n)); } else { /* including gap == 8 */ memmove(ctxt->md5_buf + ctxt->md5_i, md5_paddat, gap); md5_calc(ctxt->md5_buf, ctxt); memmove(ctxt->md5_buf, md5_paddat + gap, MD5_BUFLEN - sizeof(ctxt->md5_n)); } /* 8 byte word */ #ifndef WORDS_BIGENDIAN memmove(&ctxt->md5_buf[56], &ctxt->md5_n8[0], 8); #else ctxt->md5_buf[56] = ctxt->md5_n8[7]; ctxt->md5_buf[57] = ctxt->md5_n8[6]; ctxt->md5_buf[58] = ctxt->md5_n8[5]; ctxt->md5_buf[59] = ctxt->md5_n8[4]; ctxt->md5_buf[60] = ctxt->md5_n8[3]; ctxt->md5_buf[61] = ctxt->md5_n8[2]; ctxt->md5_buf[62] = ctxt->md5_n8[1]; ctxt->md5_buf[63] = ctxt->md5_n8[0]; #endif md5_calc(ctxt->md5_buf, ctxt); }
void md5_pad(md5_ctxt *ctxt) { u_int gap; /* Don't count up padding. Keep md5_n. */ gap = MD5_BUFLEN - ctxt->md5_i; if (gap > 8) { bcopy((void *)md5_paddat, (void *)(ctxt->md5_buf + ctxt->md5_i), gap - sizeof(ctxt->md5_n)); } else { /* including gap == 8 */ bcopy((void *)md5_paddat, (void *)(ctxt->md5_buf + ctxt->md5_i), gap); md5_calc(ctxt->md5_buf, ctxt); bcopy((void *)(md5_paddat + gap), (void *)ctxt->md5_buf, MD5_BUFLEN - sizeof(ctxt->md5_n)); } /* 8 byte word */ #if BYTE_ORDER == LITTLE_ENDIAN bcopy(&ctxt->md5_n8[0], &ctxt->md5_buf[56], 8); #endif #if BYTE_ORDER == BIG_ENDIAN ctxt->md5_buf[56] = ctxt->md5_n8[7]; ctxt->md5_buf[57] = ctxt->md5_n8[6]; ctxt->md5_buf[58] = ctxt->md5_n8[5]; ctxt->md5_buf[59] = ctxt->md5_n8[4]; ctxt->md5_buf[60] = ctxt->md5_n8[3]; ctxt->md5_buf[61] = ctxt->md5_n8[2]; ctxt->md5_buf[62] = ctxt->md5_n8[1]; ctxt->md5_buf[63] = ctxt->md5_n8[0]; #endif md5_calc(ctxt->md5_buf, ctxt); }
void md5_pad(md5_ctx *ctx) { unsigned gap; /* Don't count up padding. Keep md5_n. */ gap = MD5_BUFLEN - ctx->md5_i; if (gap > 8) { memcpy((void *)(ctx->md5_buf + ctx->md5_i), (void *)md5_paddat, gap - sizeof(ctx->md5_n)); } else { /* including gap == 8 */ memcpy((void *)(ctx->md5_buf + ctx->md5_i), (void *)md5_paddat, gap); md5_calc(ctx->md5_buf, ctx); memcpy((void *)ctx->md5_buf, (void *)(md5_paddat + gap), MD5_BUFLEN - sizeof(ctx->md5_n)); } /* 8 byte word */ #if defined(WORDS_BIGENDIAN) ctx->md5_buf[56] = ctx->md5_n8[7]; ctx->md5_buf[57] = ctx->md5_n8[6]; ctx->md5_buf[58] = ctx->md5_n8[5]; ctx->md5_buf[59] = ctx->md5_n8[4]; ctx->md5_buf[60] = ctx->md5_n8[3]; ctx->md5_buf[61] = ctx->md5_n8[2]; ctx->md5_buf[62] = ctx->md5_n8[1]; ctx->md5_buf[63] = ctx->md5_n8[0]; #else memcpy(&ctx->md5_buf[56], &ctx->md5_n8[0], 8); #endif md5_calc(ctx->md5_buf, ctx); }
void md5_loop(md5_ctxt *ctxt, u_int8_t *input, u_int len /* number of bytes */) { u_int gap, i; ctxt->md5_n += len * 8; /* byte to bit */ gap = MD5_BUFLEN - ctxt->md5_i; if (len >= gap) { bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i), gap); md5_calc(ctxt->md5_buf, ctxt); for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) { md5_calc((u_int8_t *)(input + i), ctxt); } ctxt->md5_i = len - i; bcopy((void *)(input + i), (void *)ctxt->md5_buf, ctxt->md5_i); } else { bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i), len); ctxt->md5_i += len; } }
/* * Receive and verify the result. */ static int result_recv(u_int32_t host, u_short udp_port, char *buffer, int length) { AUTH_HDR *auth; int totallen; unsigned char reply_digest[AUTH_VECTOR_LEN]; unsigned char calc_digest[AUTH_VECTOR_LEN]; int secretlen; /* VALUE_PAIR *req; */ auth = (AUTH_HDR *) buffer; totallen = ntohs(auth->length); if (totallen != length) { fprintf(stderr, "Squid_rad_auth: Received invalid reply length from server (want %d/ got %d)\n", totallen, length); return -1; } if (auth->id != request_id) { /* Duplicate response of an earlier query, ignore */ return -1; } /* Verify the reply digest */ memcpy(reply_digest, auth->vector, AUTH_VECTOR_LEN); memcpy(auth->vector, vector, AUTH_VECTOR_LEN); secretlen = strlen(secretkey); memcpy(buffer + length, secretkey, secretlen); md5_calc(calc_digest, (unsigned char *) auth, length + secretlen); if (memcmp(reply_digest, calc_digest, AUTH_VECTOR_LEN) != 0) { fprintf(stderr, "Warning: Received invalid reply digest from server\n"); return -1; } if (auth->code != PW_AUTHENTICATION_ACK) return 1; return 0; }
static inline void md5_loop_tmpl(Iterator &start, const Iterator &end, struct md5_digest_ctxt* ctxt) { uint64_t len = 0; while (start < end) { uint8_t i = 0; for (i = 0; i < MD5_BUFLEN && start < end; ++i, ++start ) { ctxt->md5_buf[i] = (uint8_t) *start; } len += i; if (MD5_BUFLEN == i) { md5_calc(ctxt->md5_buf, ctxt); } else { ctxt->md5_i = i; } } ctxt->md5_n = len * 8; /* byte to bit */ }
static int authenticate(int sockfd, const char *username, const char *passwd) { AUTH_HDR *auth; u_short total_length; u_char *ptr; int length; char passbuf[MAXPASS]; u_char md5buf[256]; int secretlen; u_char cbc[AUTH_VECTOR_LEN]; int i, j; u_int32_t ui; struct sockaddr_in saremote; fd_set readfds; socklen_t salen; int retry = retries; /* * Build an authentication request */ auth = (AUTH_HDR *) send_buffer; auth->code = PW_AUTHENTICATION_REQUEST; auth->id = ++request_id; random_vector(vector); memcpy(auth->vector, vector, AUTH_VECTOR_LEN); total_length = AUTH_HDR_LEN; ptr = auth->data; /* * User Name */ *ptr++ = PW_USER_NAME; length = strlen(username); if (length > MAXPWNAM) { length = MAXPWNAM; } *ptr++ = length + 2; memcpy(ptr, username, length); ptr += length; total_length += length + 2; /* * Password */ length = strlen(passwd); if (length > MAXPASS) { length = MAXPASS; } memset(passbuf, 0, MAXPASS); memcpy(passbuf, passwd, length); /* * Length is rounded up to multiple of 16, * and the password is encoded in blocks of 16 * with cipher block chaining */ length = ((length / AUTH_VECTOR_LEN) + 1) * AUTH_VECTOR_LEN; *ptr++ = PW_PASSWORD; *ptr++ = length + 2; secretlen = strlen(secretkey); /* Set up the Cipher block chain */ memcpy(cbc, auth->vector, AUTH_VECTOR_LEN); for (j = 0; j < length; j += AUTH_VECTOR_LEN) { /* Calculate the MD5 Digest */ strcpy((char *)md5buf, secretkey); memcpy(md5buf + secretlen, cbc, AUTH_VECTOR_LEN); md5_calc(cbc, md5buf, secretlen + AUTH_VECTOR_LEN); /* Xor the password into the MD5 digest */ for (i = 0; i < AUTH_VECTOR_LEN; i++) { *ptr++ = (cbc[i] ^= passbuf[j + i]); } } total_length += length + 2; *ptr++ = PW_NAS_PORT_ID; *ptr++ = 6; ui = htonl(nasport); memcpy(ptr, &ui, 4); ptr += 4; total_length += 6; *ptr++ = PW_NAS_PORT_TYPE; *ptr++ = 6; ui = htonl(nasporttype); memcpy(ptr, &ui, 4); ptr += 4; total_length += 6; if (*identifier) { int len = strlen(identifier); *ptr++ = PW_NAS_ID; *ptr++ = len + 2; memcpy(ptr, identifier, len); ptr += len; } else { *ptr++ = PW_NAS_IP_ADDRESS; *ptr++ = 6; ui = htonl(nas_ipaddr); memcpy(ptr, &ui, 4); ptr += 4; total_length += 6; } /* Klaus Weidner <*****@*****.**> changed this * from htonl to htons. It might have caused * you trouble or not. That depends on the byte * order of your system. * The symptom was that the radius server * ignored the requests, because they had zero * length according to the data header. */ auth->length = htons(total_length); while(retry--) { int time_spent; struct timeval sent; /* * Send the request we've built. */ gettimeofday(&sent, NULL); send(sockfd, (char *) auth, total_length, 0); while ((time_spent = time_since(&sent)) < 1000000) { struct timeval tv; int rc, len; if (!time_spent) { tv.tv_sec = 1; tv.tv_usec = 0; } else { tv.tv_sec = 0; tv.tv_usec = 1000000 - time_spent; } FD_ZERO(&readfds); FD_SET(sockfd, &readfds); if (select(sockfd + 1, &readfds, NULL, NULL, &tv) == 0) /* Select timeout */ break; salen = sizeof(saremote); len = recvfrom(sockfd, recv_buffer, sizeof(i_recv_buffer), 0, (struct sockaddr *) &saremote, &salen); if (len < 0) continue; rc = result_recv(saremote.sin_addr.s_addr, saremote.sin_port, recv_buffer, len); if (rc == 0) return 1; if (rc == 1) return 0; } } fprintf(stderr, "%s: No response from RADIUS server\n", progname); return 0; }
/*++ * Function: Get_Server_sd * * Purpose: When a client login attempt is made, fetch a usable server * socket descriptor. This means that either we reuse an * existing sd, or we open a new one. Hide that abstraction from * the caller... * * Parameters: ptr to username string * ptr to password string * const ptr to client hostname or IP string (for logging only) * * Returns: int sd on success * -1 on failure * * Authors: dgm * *-- */ extern int Get_Server_sd( char *Username, char *Password, const char *ClientAddr ) { char *fn = "Get_Server_sd()"; unsigned int HashIndex; ICC_Struct *HashEntry = NULL; char SendBuf[BUFSIZE]; unsigned int BufLen = BUFSIZE - 1; char md5pw[16]; char *tokenptr; char *endptr; char *last; ICC_Struct *ICC_Active; ICC_Struct *ICC_tptr; ITD_Struct Server; int rc; unsigned int Expiration; Expiration = PC_Struct.cache_expiration_time; memset( &Server, 0, sizeof Server ); /* need to md5 the passwd regardless, so do that now */ md5_calc( md5pw, Password, strlen( Password ) ); /* see if we have a reusable connection available */ ICC_Active = NULL; HashIndex = Hash( Username, HASH_TABLE_SIZE ); LockMutex( &mp ); /* * Now we just iterate through the linked list at this hash index until * we either find the string we're looking for or we find a NULL. */ for ( HashEntry = ICC_HashTable[ HashIndex ]; HashEntry; HashEntry = HashEntry->next ) { if ( ( strcmp( Username, HashEntry->username ) == 0 ) && ( HashEntry->logouttime > 1 ) ) { ICC_Active = HashEntry; /* * we found this username in our hash table. Need to know if * the password matches. */ if ( memcmp( md5pw, ICC_Active->hashedpw, sizeof md5pw ) ) { /* the passwords don't match. Shake this guy. */ UnLockMutex( &mp ); syslog(LOG_INFO, "LOGIN: '******' (%s) failed: password incorrect", Username, ClientAddr ); return( -1 ); } /* * We found a matching password on an inactive server socket. We * can use this guy. Before we release the mutex, set the * logouttime such that we mark this connection as "active" again. */ ICC_Active->logouttime = 0; /* * The fact that we have this stored in a table as an open server * socket doesn't really mean that it's open. The server could've * closed it on us. * We need a speedy way to make sure this is still open. * We'll set the fd to non-blocking and try to read from it. If we * get a zero back, the connection is closed. If we get * EWOULDBLOCK (or some data) we know it's still open. If we do * read data, make sure we read all the data so we "drain" any * puss that may be left on this socket. */ fcntl( ICC_Active->server_sd, F_SETFL, fcntl( ICC_Active->server_sd, F_GETFL, 0) | O_NONBLOCK ); while ( ( rc = recv( ICC_Active->server_sd, Server.ReadBuf, sizeof Server.ReadBuf, 0 ) ) > 0 ); if ( !rc ) { syslog(LOG_NOTICE, "%s: Unable to reuse server sd [%d] for user '%s' (%s). Connection closed by server.", fn, ICC_Active->server_sd, Username, ClientAddr ); ICC_Active->logouttime = 1; continue; } if ( errno != EWOULDBLOCK ) { syslog(LOG_NOTICE, "%s: Unable to reuse server sd [%d] for user '%s' (%s). recv() error: %s", fn, ICC_Active->server_sd, Username, ClientAddr, strerror( errno ) ); ICC_Active->logouttime = 1; continue; } fcntl( ICC_Active->server_sd, F_SETFL, fcntl( ICC_Active->server_sd, F_GETFL, 0) & ~O_NONBLOCK ); /* now release the mutex and return the sd to the caller */ UnLockMutex( &mp ); /* * We're reusing an existing server socket. There are a few * counters we have to deal with. */ IMAPCount->RetainedServerConnections--; IMAPCount->InUseServerConnections++; IMAPCount->TotalServerConnectionsReused++; if ( IMAPCount->InUseServerConnections > IMAPCount->PeakInUseServerConnections ) IMAPCount->PeakInUseServerConnections = IMAPCount->InUseServerConnections; syslog(LOG_INFO, "LOGIN: '******' (%s) on existing sd [%d]", Username, ClientAddr, ICC_Active->server_sd ); return( ICC_Active->server_sd ); } } UnLockMutex( &mp ); /* * We don't have an active connection for this user. * Open a connection to the IMAP server so we can attempt to login */ Server.sd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); if ( Server.sd == -1 ) { syslog(LOG_INFO, "LOGIN: '******' (%s) failed: Unable to open server socket: %s", Username, ClientAddr, strerror( errno ) ); return( -1 ); } if ( connect( Server.sd, (struct sockaddr *)&ISD.srv, sizeof(ISD.srv) ) == -1 ) { syslog(LOG_INFO, "LOGIN: '******' (%s) failed: Unable to connect to IMAP server: %s", Username, ClientAddr, strerror( errno ) ); close( Server.sd ); return( -1 ); } /* Read & throw away the banner line from the server */ if ( IMAP_Line_Read( &Server ) == -1 ) { syslog(LOG_INFO, "LOGIN: '******' (%s) failed: No banner line received from IMAP server", Username, ClientAddr ); close( Server.sd ); return( -1 ); } /* * Send the login command off to the IMAP server. */ snprintf( SendBuf, BufLen, "A0001 LOGIN %s %s\r\n", Username, Password ); if ( send( Server.sd, SendBuf, strlen(SendBuf), 0 ) == -1 ) { syslog(LOG_INFO, "LOGIN: '******' (%s) failed: send() failed attempting to send LOGIN command to IMAP server: %s", Username, ClientAddr, strerror( errno ) ); close( Server.sd ); return( -1 ); } /* * Read the server response */ if ( ( rc = IMAP_Line_Read( &Server ) ) == -1 ) { syslog(LOG_INFO, "LOGIN: '******' (%s) failed: No response from IMAP server after sending LOGIN command", Username, ClientAddr ); close( Server.sd ); return( -1 ); } /* * Try to match up the tag in the server response to the client tag. */ endptr = Server.ReadBuf + rc; tokenptr = memtok( Server.ReadBuf, endptr, &last ); if ( !tokenptr ) { /* * no tokens found in server response? Not likely, but we still * have to check. */ syslog(LOG_INFO, "LOGIN: '******' (%s) failed: server response to LOGIN command contained no tokens.", Username, ClientAddr ); close( Server.sd ); return( -1 ); } if ( memcmp( (const void *)tokenptr, (const void *)"A0001", strlen( tokenptr ) ) ) { /* * non-matching tag read back from the server... Lord knows what this * is, so we'll fail. */ syslog(LOG_INFO, "LOGIN: '******' (%s) failed: server response to LOGIN command contained non-matching tag.", Username, ClientAddr ); close( Server.sd ); return( -1 ); } /* * Now that we've matched the tags up, see if the response was 'OK' */ tokenptr = memtok( NULL, endptr, &last ); if ( !tokenptr ) { /* again, not likely but we still have to check... */ syslog(LOG_INFO, "LOGIN: '******' (%s) failed: Malformed server response to LOGIN command", Username, ClientAddr ); close( Server.sd ); return( -1 ); } if ( memcmp( (const void *)tokenptr, "OK", 2 ) ) { /* * If the server sent back a "NO" or "BAD", we can look at the actual * server logs to figure out why. We don't have to break our ass here * putting the string back together just for the sake of logging. */ syslog(LOG_INFO, "LOGIN: '******' (%s) failed: non-OK server response to LOGIN command", Username, ClientAddr ); close( Server.sd ); return( -1 ); } /* * put this in our used list and remove it from the free list */ for( ; ; ) { LockMutex( &mp ); if ( ICC_free->next ) { /* generate the hash index */ HashIndex = Hash( Username, HASH_TABLE_SIZE ); /* temporarily store the address of the next free structure */ ICC_tptr = ICC_free->next; /* * We want to add the newest "used" structure at the front of * the list at the hash index. */ ICC_free->next = ICC_HashTable[ HashIndex ]; ICC_HashTable[ HashIndex ] = ICC_free; /* * less typing and more readability, set an "active" pointer. */ ICC_Active = ICC_free; /* now point the free listhead to the next available free struct */ ICC_free = ICC_tptr; /* fill in the newest used (oxymoron?) structure */ strncpy( ICC_Active->username, Username, sizeof ICC_Active->username ); memcpy( ICC_Active->hashedpw, md5pw, sizeof ICC_Active->hashedpw ); ICC_Active->logouttime = 0; /* zero means, "it's active". */ ICC_Active->server_sd = Server.sd; UnLockMutex( &mp ); IMAPCount->InUseServerConnections++; IMAPCount->TotalServerConnectionsCreated++; if ( IMAPCount->InUseServerConnections > IMAPCount->PeakInUseServerConnections ) IMAPCount->PeakInUseServerConnections = IMAPCount->InUseServerConnections; syslog(LOG_INFO, "LOGIN: '******' (%s) on new sd [%d]", Username, ClientAddr, Server.sd ); return( Server.sd ); } /* * There weren't any free ICC structs. Try to free one. Make sure * we unlock the mutex, since ICC_Recycle needs to obtain it. */ UnLockMutex( &mp ); Expiration = abs( Expiration / 2 ); /* * Eventually, we have to fail */ if ( Expiration <= 2 ) { syslog(LOG_INFO, "LOGIN: '******' (%s) failed: Out of free ICC structs.", Username, ClientAddr ); close( Server.sd ); return( -1 ); } ICC_Recycle( Expiration ); } }