diff --git a/CocoaMento-Src/CocoaMento.pro b/CocoaMento-Src/CocoaMento.pro
new file mode 100644
index 0000000..1a45aca
--- /dev/null
+++ b/CocoaMento-Src/CocoaMento.pro
@@ -0,0 +1,50 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2011-03-29T16:22:30
+#
+#-------------------------------------------------
+
+QT += core gui network
+
+CONFIG += qthread
+
+TARGET = CocoaMento
+TEMPLATE = app
+LIBS += -framework Cocoa \
+ -framework Security \
+ -framework Growl
+
+SOURCES += main.cpp\
+ statusicon.mm \
+ menuitem.mm \
+ cocoamenuitemvirtual.mm \
+ qtport.cpp \
+ cocoaappinitlizer.mm \
+ menuviewitem.mm\
+ menu.mm \
+ configview.cpp \
+ mento.cpp \
+ accountform.cpp \
+ mentothread.cpp \
+ guite.cpp
+
+HEADERS += \
+ statusicon.h \
+ menuitem.h \
+ cocoamenuitemvirtual.h \
+ qtport.h \
+ cocoaappinitlizer.h \
+ menuviewitem.h \
+ menu.h \
+ configview.h \
+ mento.h \
+ accountform.h \
+ mentothread.h \
+ guite.h \
+
+FORMS += \
+ configview.ui \
+ accountform.ui \
+ guite.ui
+
+RESOURCES +=
diff --git a/CocoaMento-Src/CocoaMento.pro.user b/CocoaMento-Src/CocoaMento.pro.user
new file mode 100644
index 0000000..3c49ffc
--- /dev/null
+++ b/CocoaMento-Src/CocoaMento.pro.user
@@ -0,0 +1,113 @@
+
+
+
+ ProjectExplorer.Project.ActiveTarget
+ 0
+
+
+ ProjectExplorer.Project.EditorSettings
+
+ System
+
+
+
+ ProjectExplorer.Project.Target.0
+
+ Desktop
+ Qt4ProjectManager.Target.DesktopTarget
+ 1
+ 0
+
+
+ qmake
+ QtProjectManager.QMakeBuildStep
+
+
+
+ Make
+ Qt4ProjectManager.MakeStep
+ false
+
+
+
+ 2
+
+ Make
+ Qt4ProjectManager.MakeStep
+ true
+
+ clean
+
+
+
+ 1
+ false
+
+ Debug
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 2
+ /Users/shanzi/Documents/Codes/CocoaMento-build-desktop
+ 2
+ 0
+ true
+
+
+
+ qmake
+ QtProjectManager.QMakeBuildStep
+
+
+
+ Make
+ Qt4ProjectManager.MakeStep
+ false
+
+
+
+ 2
+
+ Make
+ Qt4ProjectManager.MakeStep
+ true
+
+ clean
+
+
+
+ 1
+ false
+
+ Release
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 0
+ /Users/shanzi/Documents/Codes/CocoaMento-build-desktop
+ 2
+ 0
+ true
+
+ 2
+
+ CocoaMento
+ Qt4ProjectManager.Qt4RunConfiguration
+ 2
+
+ CocoaMento.pro
+ false
+ false
+
+ false
+ false
+
+
+ 1
+
+
+
+ ProjectExplorer.Project.TargetCount
+ 1
+
+
+ ProjectExplorer.Project.Updater.FileVersion
+ 4
+
+
diff --git a/CocoaMento-Src/README b/CocoaMento-Src/README
new file mode 100644
index 0000000..3388b5f
--- /dev/null
+++ b/CocoaMento-Src/README
@@ -0,0 +1,15 @@
+CocoaMento是一个使用Cocoa和Qt代码混合编写的校园网登陆客户端图形界面加壳程序,目前只适用于Mac OS X,在10.6以上版本测试通过。
+
+编译注意事项
+
+1,因为使用Qt框架,编译前需前往Qt官网下载Qt SDK,届时打开CocoaMento.pro文件直接编译即可。
+2,为了方便mentohust进程和GUI的交互,对mentohust代码略有修改,主要修改在于更改了程序向外输出的字符串。代码在mentohust-src文件夹中,只需在对应目录下执行make命令即可
+3,mentohust-src/auth.c是为了在Mac OS下完成对程序权限的申请而特制的一个小程序,使用gcc auth.c -o auth命令直接编译即可
+4,最新版本的CocoaMento加入了Growl框架的支持,编译前请先下载配置开源的Growl SDK
+
+打包注意事项
+
+1,Mac OS的App存放在bundle结构的目录体系下,编译好以后,应将编译所得的mentohust文件和auth文件移动到Contents/MacOS/目录下。
+2,为了方便权限管理,采用了私用pcap的方法,请将系统内的libpcap.dylib库复制或制作快捷连接,放置于Contents/Frameworks目录下
+3,程序的Contents/Resources文件夹内可以存放图标等资源,Contents/Resources/data/文件夹是默认存放官方锐捷数据文件的目录
+
diff --git a/CocoaMento-Src/StatusIcon.h b/CocoaMento-Src/StatusIcon.h
new file mode 100644
index 0000000..d3d9af4
--- /dev/null
+++ b/CocoaMento-Src/StatusIcon.h
@@ -0,0 +1,33 @@
+//
+// StatusIcon.h
+// HelloCocoa
+//
+// Created by 云尔 on 11-3-28.
+// Copyright 2011年 __MyCompanyName__. All rights reserved.
+//
+
+#ifndef _STATUS_ICON_H
+#define _STATUS_ICON_H
+#include "menu.h"
+#include
+
+class StatusIcon
+{
+public:
+ StatusIcon();
+ ~StatusIcon();
+ void showIcon();
+ void hideIcon();
+ void setHighlightMode(bool highlight);
+ bool highlightMode();
+ void setMenu(Menu* menu);
+ void setIcon(const char* name);
+
+private:
+ Menu* menu;
+ class CocoaBridge;
+ CocoaBridge* b;
+};
+
+
+#endif
diff --git a/CocoaMento-Src/StatusIconBase.h b/CocoaMento-Src/StatusIconBase.h
new file mode 100644
index 0000000..9051a74
--- /dev/null
+++ b/CocoaMento-Src/StatusIconBase.h
@@ -0,0 +1,17 @@
+//
+// StatusIconBase.h
+// HelloCocoa
+//
+// Created by 云尔 on 11-3-29.
+// Copyright 2011年 __MyCompanyName__. All rights reserved.
+//
+#ifndef STATUS_ICON_BASE
+#define STATUS_ICON_BASE
+
+
+//class StatusIconBase; {
+//public:
+// void handleTrigger(long id);
+//};
+
+#endif
\ No newline at end of file
diff --git a/CocoaMento-Src/accountform.cpp b/CocoaMento-Src/accountform.cpp
new file mode 100644
index 0000000..fba5f40
--- /dev/null
+++ b/CocoaMento-Src/accountform.cpp
@@ -0,0 +1,136 @@
+#include "accountform.h"
+#include "ui_accountform.h"
+#include
+
+static const unsigned char base64Tab[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"};
+static const char xorRuijie[] = {"~!:?$*<(qw2e5o7i8x12c6m67s98w43d2l45we82q3iuu1z4xle23rt4oxclle34e54u6r8m"};
+
+static int encodePass(char *dst, const char *osrc) {
+ unsigned char in[3], buf[70];
+ unsigned char *src = buf;
+ int sz = strlen(osrc);
+ int i, len;
+ if (sizeof(xorRuijie) < sz)
+ return -1;
+ for(i=0; i 0) {
+ for (len=0, i=0; i<3; i++, sz--) {
+ if (sz > 0) {
+ len++;
+ in[i] = src[i];
+ } else in[i] = 0;
+ }
+ src += 3;
+ if (len) {
+ dst[0] = base64Tab[ in[0] >> 2 ];
+ dst[1] = base64Tab[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
+ dst[2] = len > 1 ? base64Tab[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '=';
+ dst[3] = len > 2 ? base64Tab[ in[2] & 0x3f ] : '=';
+ dst += 4;
+ }
+ }
+ *dst = '\0';
+ return 0;
+}
+
+static int decodePass(char *dst, const char *src) {
+ unsigned esi = 0, idx = 0;
+ int i=0, j=0, equal=0;
+ for(; src[i]!='\0'; i++) {
+ if (src[i] == '=') {
+ if (++equal > 2)
+ return -1;
+ } else {
+ for(idx=0; base64Tab[idx]!='\0'; idx++) {
+ if(base64Tab[idx] == src[i])
+ break;
+ }
+ if (idx == 64)
+ return -1;
+ esi += idx;
+ }
+ if(i%4 == 3) {
+ dst[j++] = (char)(esi>>16);
+ if(equal < 2)
+ dst[j++] = (char)(esi>>8);
+ if(equal < 1)
+ dst[j++] = (char)esi;
+ esi = 0;
+ equal = 0;
+ }
+ esi <<= 6;
+ }
+ if (i%4!=0 || sizeof(xorRuijie)setupUi(this);
+ setWindowFlags(Qt::WindowStaysOnTopHint|Qt::CustomizeWindowHint|Qt::WindowCloseButtonHint);
+ ref=settingref;
+ connect(ui->Cancel,SIGNAL(clicked()),this,SLOT(close()));
+ connect(ui->Confirm,SIGNAL(clicked()),this,SLOT(Confirm()));
+ connect(ui->Name,SIGNAL(returnPressed()),this,SLOT(Confirm()));
+ connect(ui->Pass,SIGNAL(returnPressed()),this,SLOT(Confirm()));
+}
+
+AccountForm::~AccountForm()
+{
+ delete ui;
+}
+
+void AccountForm::setAccount(const char *name, const char *pass)
+{
+ char pw[65*4/3]={0};
+ if(ref==0)return;
+ if(name!=0) ref->setValue(tr("Username"),tr(name));
+ if(pass!=0)
+ {
+
+ if(encodePass(pw,pass))
+ {
+ QMessageBox::critical(this,"错误","设定密码失败,无法进行加密操作!",QMessageBox::Cancel,QMessageBox::NoButton);
+ return;
+ }
+ ref->setValue(tr("EncodePass"),tr(pw));
+ }
+ if(!ref->isWritable()){
+ QMessageBox::critical(this,"错误","写入配置文件失败!",QMessageBox::Cancel,QMessageBox::NoButton);
+ return;
+ }
+ ui->Name->setText(ref->value(tr("Username")).toString());
+ //qDebug()<value(tr("Username")).toString();
+ if(decodePass(pw,ref->value(tr("EncodePass")).toString().toUtf8().data()))
+ {
+ QMessageBox::critical(this,"错误","解析密码失败!请重设密码!",QMessageBox::Ok,QMessageBox::NoButton);
+ ui->Pass->setText(tr(""));
+ ref->remove(tr("EncodePass"));
+ this->show();
+ }
+ else ui->Pass->setText(tr(pw));
+}
+void AccountForm::show()
+{
+ setAccount();
+ QWidget::show();
+}
+
+void AccountForm::Confirm()
+{
+ if(ui->Name->text().length()==0 || ui->Pass->text().length()==0)
+ {
+ QMessageBox::warning(this,"Warning","用户名和密码不能为空!",QMessageBox::Ok,QMessageBox::NoButton);
+ return;
+ }
+ setAccount(ui->Name->text().toUtf8().data(),ui->Pass->text().toUtf8().data());
+ QWidget::close();
+}
diff --git a/CocoaMento-Src/accountform.h b/CocoaMento-Src/accountform.h
new file mode 100644
index 0000000..2b9c5df
--- /dev/null
+++ b/CocoaMento-Src/accountform.h
@@ -0,0 +1,32 @@
+#ifndef ACCOUNTFORM_H
+#define ACCOUNTFORM_H
+
+#include
+#include
+#include
+
+namespace Ui {
+ class AccountForm;
+}
+
+class AccountForm : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit AccountForm(QSettings* settingref,QWidget *parent = 0);
+ ~AccountForm();
+
+ void setAccount(const char* name=0,const char* pass=0);
+ const char * Name();
+ const char * Pass();
+public slots:
+ void show();
+ void Confirm();
+
+private:
+ Ui::AccountForm *ui;
+ QSettings* ref;
+};
+
+#endif // ACCOUNTFORM_H
diff --git a/CocoaMento-Src/accountform.ui b/CocoaMento-Src/accountform.ui
new file mode 100644
index 0000000..0cf833e
--- /dev/null
+++ b/CocoaMento-Src/accountform.ui
@@ -0,0 +1,531 @@
+
+
+ AccountForm
+
+
+ Qt::WindowModal
+
+
+
+ 0
+ 0
+ 270
+ 200
+
+
+
+
+ 270
+ 200
+
+
+
+
+ 270
+ 200
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 127
+ 127
+ 127
+
+
+
+
+
+
+ 170
+ 170
+ 170
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 220
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 127
+ 127
+ 127
+
+
+
+
+
+
+ 170
+ 170
+ 170
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 220
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+
+ 127
+ 127
+ 127
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 127
+ 127
+ 127
+
+
+
+
+
+
+ 170
+ 170
+ 170
+
+
+
+
+
+
+ 127
+ 127
+ 127
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 127
+ 127
+ 127
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 220
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+ Qt::StrongFocus
+
+
+
+
+
+
+
+ 10
+ 10
+ 251
+ 141
+
+
+
+ 用户名和密码设置
+
+
+ -
+
+
+ 用户名:
+
+
+
+ -
+
+
+ 65
+
+
+
+ -
+
+
+ 密码:
+
+
+
+ -
+
+
+ 65
+
+
+ QLineEdit::Password
+
+
+
+ -
+
+
+ 设置完成后立即开始连接
+
+
+
+
+
+
+
+
+ 180
+ 160
+ 81
+ 32
+
+
+
+ 确定
+
+
+
+
+
+ 100
+ 160
+ 81
+ 32
+
+
+
+ 取消
+
+
+
+
+
+
diff --git a/CocoaMento-Src/cocoaappinitlizer.h b/CocoaMento-Src/cocoaappinitlizer.h
new file mode 100644
index 0000000..2872f7f
--- /dev/null
+++ b/CocoaMento-Src/cocoaappinitlizer.h
@@ -0,0 +1,34 @@
+#ifndef COCOAAPPINITLIZER_H
+#define COCOAAPPINITLIZER_H
+
+namespace CocoaInitialize{
+
+
+
+class CocoaAppInitlizer
+{
+public:
+ CocoaAppInitlizer();
+ bool checkRunning();
+ void requestFocus();
+ ~CocoaAppInitlizer();
+
+private:
+ class AutoReleasePoolWarp;
+ AutoReleasePoolWarp* w;
+};
+
+
+
+const char* mainBundlePath();
+int auth();
+void initCocoaApp();
+int exitCocoaApp();
+CocoaAppInitlizer* DefaultApp();
+void growl(const char*title,const char* msg);
+
+}
+
+#endif // COCOAAPPINITLIZER_H
+
+
diff --git a/CocoaMento-Src/cocoaappinitlizer.mm b/CocoaMento-Src/cocoaappinitlizer.mm
new file mode 100644
index 0000000..22a79d4
--- /dev/null
+++ b/CocoaMento-Src/cocoaappinitlizer.mm
@@ -0,0 +1,145 @@
+#include "cocoaappinitlizer.h"
+#import
+#import
+#import
+
+@interface Growl : NSObject {
+}
+@end
+@implementation Growl
+- (id)init
+{
+ self = [super init];
+ if (self) {
+ [GrowlApplicationBridge setGrowlDelegate: self];
+ }
+
+ return self;
+}
+
+- (void)dealloc
+{
+ [super dealloc];
+}
+
+- (void) notify:(NSString*)title
+ detail:(NSString*)det
+{
+ [GrowlApplicationBridge notifyWithTitle: title
+ description: det
+ notificationName: @"CocoaMento"
+ iconData: nil
+ priority: 0
+ isSticky: NO
+ clickContext: nil];
+}
+
+- (NSDictionary *) registrationDictionaryForGrowl
+{
+ NSArray *notifications;
+ notifications = [NSArray arrayWithObject: @"CocoaMento"];
+
+ NSDictionary *dict;
+
+ dict = [NSDictionary dictionaryWithObjectsAndKeys:
+ notifications, GROWL_NOTIFICATIONS_ALL,
+ notifications, GROWL_NOTIFICATIONS_DEFAULT, nil];
+
+ return (dict);
+
+}
+
+@end
+Growl* growlproxy;
+
+namespace CocoaInitialize{
+
+CocoaAppInitlizer* defaultApp;
+
+
+class CocoaAppInitlizer::AutoReleasePoolWarp
+{
+public:
+ NSAutoreleasePool * releasepool;
+ NSConnection *connection;
+
+};
+
+
+CocoaAppInitlizer::CocoaAppInitlizer()
+{
+ w=new AutoReleasePoolWarp();
+ w->releasepool=[[NSAutoreleasePool alloc] init];
+
+}
+CocoaAppInitlizer::~CocoaAppInitlizer()
+{
+ [w->connection release];
+ free(w->releasepool);
+ delete w;
+}
+
+
+bool CocoaAppInitlizer::checkRunning()
+{
+ w->connection= [NSConnection connectionWithRegisteredName:@"com.myapp.cocoamento" host:nil];
+ if([w->connection isValid]==NO){
+ [w->connection release];
+ w->connection=[[NSConnection alloc] init];
+ [w->connection registerName:@"com.myapp.cocoamento"];
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+void CocoaAppInitlizer::requestFocus()
+{
+ [NSApp activateIgnoringOtherApps:YES];
+}
+
+const char* mainBundlePath()
+{
+ if(defaultApp==NULL) return "";
+ return [[[NSBundle mainBundle] bundlePath] UTF8String];
+}
+
+int auth()
+{
+ if(defaultApp==NULL) return 0;
+ AuthorizationRef authMento;
+ NSString *auth = [[[NSBundle mainBundle] bundlePath] stringByAppendingString: @"/Contents/MacOS/auth"];
+ AuthorizationFlags authFlags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights;
+ AuthorizationItem authItems[] = {kAuthorizationRightExecute, strlen([auth UTF8String]), (void*)auth, 0};
+ AuthorizationRights authRights = {sizeof(authItems)/sizeof(AuthorizationItem), authItems};
+ if(AuthorizationCreate(&authRights, kAuthorizationEmptyEnvironment, authFlags, &authMento) != errAuthorizationSuccess) return 0;
+ if(AuthorizationExecuteWithPrivileges(authMento, [auth UTF8String], kAuthorizationFlagDefaults,NULL, NULL))return 0;
+ sleep(800);
+ if(AuthorizationExecuteWithPrivileges(authMento, [auth UTF8String], kAuthorizationFlagDefaults,NULL, NULL)) return 0;
+ return 1;
+}
+void initCocoaApp(){
+ if(defaultApp==NULL)
+ defaultApp=new CocoaAppInitlizer();
+}
+int exitCocoaApp()
+{
+ if(growlproxy!=NULL) [growlproxy release];
+ if(defaultApp!=NULL) delete defaultApp;
+ return 0;
+}
+
+CocoaAppInitlizer* DefaultApp()
+{
+ return defaultApp;
+}
+
+void growl(const char*title,const char *msg)
+{
+ if(growlproxy==NULL) growlproxy=[[Growl alloc] init];
+ [growlproxy notify:[NSString stringWithUTF8String:title] detail:[NSString stringWithUTF8String:msg]];
+
+}
+}
diff --git a/CocoaMento-Src/cocoamenuitemvirtual.h b/CocoaMento-Src/cocoamenuitemvirtual.h
new file mode 100644
index 0000000..3b919e8
--- /dev/null
+++ b/CocoaMento-Src/cocoamenuitemvirtual.h
@@ -0,0 +1,15 @@
+#ifndef COCOAMENUITEMVIRTUAL_H
+#define COCOAMENUITEMVIRTUAL_H
+
+
+
+class CocoaMenuItemVirtual
+{
+public:
+ CocoaMenuItemVirtual();
+ virtual void doTrigger();
+ ~CocoaMenuItemVirtual();
+ void* port;
+};
+
+#endif // COCOAMENUITEMVIRTUAL_H
diff --git a/CocoaMento-Src/cocoamenuitemvirtual.mm b/CocoaMento-Src/cocoamenuitemvirtual.mm
new file mode 100644
index 0000000..05a1e0b
--- /dev/null
+++ b/CocoaMento-Src/cocoamenuitemvirtual.mm
@@ -0,0 +1,20 @@
+#include "cocoamenuitemvirtual.h"
+#include "qtport.h"
+
+
+CocoaMenuItemVirtual::CocoaMenuItemVirtual()
+{
+ port=(void *)(new QtPort());
+}
+
+void CocoaMenuItemVirtual::doTrigger()
+{
+ ((QtPort*)port)->emitEvent();
+}
+
+CocoaMenuItemVirtual::~CocoaMenuItemVirtual()
+{
+ delete (QtPort*)port;
+}
+
+
diff --git a/CocoaMento-Src/configview.cpp b/CocoaMento-Src/configview.cpp
new file mode 100644
index 0000000..5597c51
--- /dev/null
+++ b/CocoaMento-Src/configview.cpp
@@ -0,0 +1,168 @@
+#include "configview.h"
+#include "ui_configview.h"
+#include "cocoaappinitlizer.h"
+#include
+
+ConfigView::ConfigView() :
+ QMacNativeWidget(0),
+ ui(new Ui::ConfigView)
+{
+ ui->setupUi(this);
+ const QSettings::Format MentoFormat=QSettings::registerFormat(tr("mento"),readMentoFile,writeMentoFile,Qt::CaseSensitive);
+ config=new QSettings(tr("%1/Contents/MacOS/mentohust.conf").arg(CocoaInitialize::mainBundlePath()),MentoFormat);
+ accountform=new AccountForm(config);
+
+ getAdapter();
+
+ if(readConfig())
+ {
+ QMessageBox::warning(this,tr("警告"),tr("读取配置文件失败,所有配置参数将会被重置为默认值!"),QMessageBox::Ok,QMessageBox::NoButton);
+ saveConfig(true);
+ }
+
+ connect(ui->AccountSetting,SIGNAL(clicked()),accountform,SLOT(show()));
+
+ connect(ui->StartMode,SIGNAL(currentIndexChanged(int)),this,SLOT(saveConfig()));
+ connect(ui->DHCPMode,SIGNAL(currentIndexChanged(int)),this,SLOT(saveConfig()));
+ connect(ui->NetInterface,SIGNAL(currentIndexChanged(int)),this,SLOT(saveConfig()));
+ connect(ui->RestartWait,SIGNAL(valueChanged(int)),this,SLOT(saveConfig()));
+ //connect(ui->Version,SIGNAL(editingFinished()),this,SLOT(saveConfig()));
+ connect(ui->Timeout,SIGNAL(valueChanged(int)),this,SLOT(saveConfig()));
+ connect(ui->EchoInterval,SIGNAL(valueChanged(int)),this,SLOT(saveConfig()));
+ connect(ui->GrowlStatus,SIGNAL(stateChanged(int)),this,SLOT(saveConfig()));
+ connect(ui->AutoConnect,SIGNAL(stateChanged(int)),this,SLOT(saveConfig()));
+ connect(ui->Version,SIGNAL(clicked()),this,SLOT(showVersionInputDialog()));
+}
+
+void ConfigView::resetConfig()
+{
+ saveConfig(true);
+}
+
+
+int ConfigView::readConfig()
+{
+ bool ok=true;
+ ui->StartMode->setCurrentIndex(config->value(tr("StartMode")).toInt(&ok));
+ if(!ok)return 1;
+ ui->EchoInterval->setValue(config->value(tr("EchoInterval")).toInt(&ok));
+ if(!ok)return 1;
+ ui->Version->setText(config->value(tr("Version")).toString());
+ ui->DHCPMode->setCurrentIndex(config->value(tr("DhcpMode")).toInt(&ok));
+ if(!ok)return 1;
+ ui->RestartWait->setValue(config->value(tr("RestartWait")).toInt(&ok));
+ if(!ok)return 1;
+ ui->Timeout->setValue(config->value(tr("Timeout")).toInt(&ok));
+ if(!ok)return 1;
+ ui->NetInterface->setCurrentIndex(ui->NetInterface->findText(config->value(tr("Nic")).toString()));
+ ui->GrowlStatus->setChecked(config->value(tr("AllowError")).toBool());
+ ui->AutoConnect->setChecked(config->value(tr("AutoConnect")).toBool());
+ return 0;
+}
+
+QSettings* ConfigView::Config()
+{
+ return config;
+}
+
+void ConfigView::showVersionInputDialog()
+{
+ bool ok=false;
+ QString v=QInputDialog::getText(0,tr("请输入版本号"),
+ tr("请输入希望CocoaMento被识别为的版本号。\n此设置视不同学校的情况不同,效果不同。\n如若需要通过V2认证,请参考使用说明设定必须的数据文件。"),
+ QLineEdit::Normal,ui->Version->text(),
+ &ok
+ );
+ if(ok){
+ ui->Version->setText(v);
+ saveConfig();
+ }
+}
+
+void ConfigView::saveConfig(bool reset)
+{
+ if(reset)
+ {
+ ui->EchoInterval->setValue(30);
+ ui->StartMode->setCurrentIndex(1);
+ ui->Version->setText(tr("3.95_1225"));
+ ui->DHCPMode->setCurrentIndex(2);
+ ui->RestartWait->setValue(15);
+ ui->Timeout->setValue(8);
+ ui->NetInterface->setCurrentIndex(-1);
+ ui->GrowlStatus->setChecked(false);
+ ui->AutoConnect->setChecked(false);
+ }
+ config->setValue(tr("EchoInterval"),QVariant(ui->EchoInterval->value()));
+ config->setValue(tr("StartMode"),QVariant(ui->StartMode->currentIndex()));
+ config->setValue(tr("Version"),QVariant(ui->Version->text()));
+ config->setValue(tr("DhcpMode"),QVariant(ui->DHCPMode->currentIndex()));
+ config->setValue(tr("RestartWait"),QVariant(ui->RestartWait->value()));
+ config->setValue(tr("Timeout"),QVariant(ui->Timeout->value()));
+ config->setValue(tr("Nic"),QVariant(ui->NetInterface->currentText()));
+ config->setValue(tr("GrowlStatus"),QVariant(ui->GrowlStatus->isChecked()));
+ config->setValue(tr("AutoConnect"),QVariant(ui->AutoConnect->isChecked()));
+}
+
+void ConfigView::getAdapter()
+{
+ QList nis=QNetworkInterface::allInterfaces();
+ if(nis.length()==0) {
+ ui->NetInterface->setCurrentIndex(-1);
+ while(ui->NetInterface->count()>0) ui->NetInterface->removeItem(0);
+ return;
+ }
+ foreach(QNetworkInterface ni,nis)
+ ui->NetInterface->addItem(ni.name());
+}
+
+bool ConfigView::autoConnect()
+{
+ return config->value(tr("AutoConnect")).toBool();
+}
+bool ConfigView::growlStatus()
+{
+ return config->value(tr("GrowlStatus")).toBool();
+}
+
+ConfigView::~ConfigView()
+{
+ accountform->hide();
+ accountform->deleteLater();
+ delete ui;
+}
+
+
+bool readMentoFile(QIODevice &device, QSettings::SettingsMap &map)
+{
+ QStringList stl;
+ QString str;
+ QTextStream ts(&device);
+ while(!ts.atEnd())
+ {
+ str=ts.readLine();
+ if(str.at(0)==QChar(';')||str.at(0)==QChar('#')) continue;
+ if (str==QString("[MentoHUST]")) continue;
+ else
+ {
+ stl=str.split(QChar('='));
+ if(stl.length()==2) map.insert(stl.at(0),QVariant(stl.at(1)));
+ else if(stl.at(0)==QString("EncodePass"))
+ {
+ map.insert(stl.at(0),QVariant(str.mid(11)));
+ }
+ else return false;
+ }
+ }
+ return true;
+}
+bool writeMentoFile(QIODevice &device, const QSettings::SettingsMap &map)
+{
+
+ device.write("[MentoHUST]\n");
+ foreach(QString key,map.keys())
+ {
+ device.write(QString("%1=%2\n").arg(key).arg(map.value(key).toString()).toUtf8().data());
+ }
+ return true;
+}
diff --git a/CocoaMento-Src/configview.h b/CocoaMento-Src/configview.h
new file mode 100644
index 0000000..0b69d5a
--- /dev/null
+++ b/CocoaMento-Src/configview.h
@@ -0,0 +1,46 @@
+#ifndef CONFIGVIEW_H
+#define CONFIGVIEW_H
+
+#include
+#include
+#include "accountform.h"
+#include
+#include
+#include
+
+
+
+namespace Ui {
+ class ConfigView;
+}
+bool readMentoFile(QIODevice &device,QSettings::SettingsMap &map);
+bool writeMentoFile(QIODevice &device,const QSettings::SettingsMap &map);
+
+
+class ConfigView : public QMacNativeWidget
+{
+ Q_OBJECT
+
+public:
+ explicit ConfigView();
+ bool autoConnect();
+ bool growlStatus();
+ QSettings* Config();
+
+ ~ConfigView();
+public slots:
+ void saveConfig(bool reset=false);
+ void resetConfig();
+ void getAdapter();
+ void showVersionInputDialog();
+
+
+private:
+ int readConfig();
+ Ui::ConfigView *ui;
+ AccountForm* accountform;
+ QSettings* config;
+
+};
+
+#endif // CONFIGVIEW_H
diff --git a/CocoaMento-Src/configview.ui b/CocoaMento-Src/configview.ui
new file mode 100644
index 0000000..6c331ff
--- /dev/null
+++ b/CocoaMento-Src/configview.ui
@@ -0,0 +1,223 @@
+
+
+ ConfigView
+
+
+
+ 0
+ 0
+ 280
+ 400
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 280
+ 430
+
+
+
+ Form
+
+
+ -
+
+
+ 账号设置
+
+
+
+ -
+
+
+
+
+
+
-
+
+
+ 2
+
+
-
+
+ 不使用
+
+
+ -
+
+ 二次认证
+
+
+ -
+
+ 认证后获取
+
+
+ -
+
+ 认证前获取
+
+
+
+
+ -
+
+
+ DHCP 方式:
+
+
+
+ -
+
+
+ 使用网卡:
+
+
+
+ -
+
+
+ -
+
+
+ 认证超时:
+
+
+
+ -
+
+
+ 响应间隔:
+
+
+
+ -
+
+
+ 失败等待:
+
+
+
+ -
+
+
+ 5
+
+
+ 90
+
+
+ 8
+
+
+
+ -
+
+
+ 5
+
+
+ 300
+
+
+ 30
+
+
+
+ -
+
+
+ 5
+
+
+ 90
+
+
+ 15
+
+
+
+ -
+
+
+ 允许失败次数:
+
+
+
+ -
+
+
+ -
+
+
+ 认证方式:
+
+
+
+ -
+
+
+ 1
+
+
-
+
+ 标准
+
+
+ -
+
+ 锐捷私有
+
+
+ -
+
+ 塞尔认证
+
+
+
+
+ -
+
+
+ 客户端版本号:
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+ -
+
+
+ 显示全部Growl信息(将会产生大量消息)
+
+
+ false
+
+
+
+ -
+
+
+ 自动登陆
+
+
+
+
+
+
+
+
diff --git a/CocoaMento-Src/guite.cpp b/CocoaMento-Src/guite.cpp
new file mode 100644
index 0000000..e0faec0
--- /dev/null
+++ b/CocoaMento-Src/guite.cpp
@@ -0,0 +1,26 @@
+#include "guite.h"
+#include "ui_guite.h"
+
+Guite::Guite(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::Guite)
+{
+ ui->setupUi(this);
+}
+
+Guite::~Guite()
+{
+ delete ui;
+}
+
+void Guite::showAbout()
+{
+ ui->Direction->setCurrentIndex(0);
+ this->show();
+}
+
+void Guite::showHelp()
+{
+ ui->Direction->setCurrentIndex(1);
+ this->show();
+}
diff --git a/CocoaMento-Src/guite.h b/CocoaMento-Src/guite.h
new file mode 100644
index 0000000..45fc590
--- /dev/null
+++ b/CocoaMento-Src/guite.h
@@ -0,0 +1,24 @@
+#ifndef GUITE_H
+#define GUITE_H
+
+#include
+
+namespace Ui {
+ class Guite;
+}
+
+class Guite : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit Guite(QWidget *parent = 0);
+ ~Guite();
+public slots:
+ void showAbout();
+ void showHelp();
+private:
+ Ui::Guite *ui;
+};
+
+#endif // GUITE_H
diff --git a/CocoaMento-Src/guite.ui b/CocoaMento-Src/guite.ui
new file mode 100644
index 0000000..60becb9
--- /dev/null
+++ b/CocoaMento-Src/guite.ui
@@ -0,0 +1,123 @@
+
+
+ Guite
+
+
+
+ 0
+ 0
+ 519
+ 382
+
+
+
+
+
+
+ -
+
+
+ 0
+
+
+
+ 关于 CocoaMento
+
+
+
-
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:22pt; font-weight:600; color:#0000ff;">关于CocoaMento 0.1b</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; color:#000000;">本程序使用Mentohust原程序辅助Qt(详见关于Qt)以及Cocoa框架,为Mac用户提供了一个带有图形界面的校园网登录客户端。此客户端认证算法基于Mentohust 0.3.1 。为了方便图形界面交互,对原代码有少量修改。Mentohust所有相关代码版权归属Mentohust开发项目团队所有。</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt; color:#000000;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; color:#000000;">使用须知:</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; color:#000000;">1、本程序只支持V2校验,暂不支持V3校验。</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; color:#000000;">2、默认用于伪装的数据文件取自锐捷登陆客户端3.95_1225,如需替换,请自行在程序处点击鼠标右键,选择“显示包内容”选项,替换“Contents/Resources/data"文件夹下的对应文件。</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; color:#000000;">3、第一次使用前请先自习阅读使用说明,进行程序设置。</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; color:#000000;">4、本程序现属于测试版本,</span><span style=" font-size:12pt; color:#ff0000;">可能会出现各种不稳定和错误现象,请谨慎使用。</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; color:#000000;">5、本程序一切使用后果由用户自己承担,作者不为因程序缺陷而导致的任何后果负责。</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; color:#000000;">6、使用本程序需同时遵守 Mentohust 程序使用须知,请仔细阅读下方”关于Mentohust“。</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; color:#000000;">7、本程序欢迎bug反馈,但不提供任何解决问题的服务和帮助。</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt; color:#000000;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; color:#000000;">作者邮箱:</span><a href="mailto:yun.er.run@gmail.com"><span style=" text-decoration: underline; color:#0000ff;">yun.er.run@gmail.com</span></a></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; color:#000000;">作者主页:</span><a href="ant.isnot.tk"><span style=" text-decoration: underline; color:#0000ff;">ant.isnot.tk</span></a></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; text-decoration: underline; color:#0000ff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:22pt; font-weight:600; color:#0000ff;">关于Mentohust 0.3.1</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1、本程序所有涉及锐捷赛尔认证的功能均是来自前辈公开代码及抓包分析。</p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">2、本程序于个人仅供学习,于他人仅供方便认证,不得使用本程序有意妨害锐捷赛尔认证机制及相关方利益。</p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">3、一切使用后果由用户自己承担。</p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">4、本程序不提供任何服务及保障,编写及维护纯属个人爱好,随时可能被终止。</p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">5、使用本程序者,即表示同意该声明。谢谢合作。</p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">源码可在项目主页获取:<a href="http://mentohust.googlecode.com/"><span style=" text-decoration: underline; color:#0000ff;">http://mentohust.googlecode.com/</span></a></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">联系作者:在<a href="http://mentohust.googlecode.com/"><span style=" text-decoration: underline; color:#0000ff;">http://mentohust.googlecode.com/</span></a>留言或Email:<a href="mailto:mentohust@ehust.co.cc"><span style=" text-decoration: underline; color:#0000ff;">mentohust@ehust.co.cc</span></a></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html>
+
+
+
+
+
+
+
+ 使用说明
+
+
+ -
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt; color:#ff6666;">本程序使用具有一定风险,使用前请仔细阅读本文档!!!</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:14pt; color:#ff6666;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">一.运行</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">双击程序图标即可运行本程序。程序运行后将会在屏幕右上角任务栏中添加一个新图标,不会在Dock上产生任何图标。第一次运行程序请先进行设置。</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">二.设置</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">点击图标,鼠标移动到“偏好设置”菜单项,将会显示出设置面板。在设置面板中可进行各种相关设置。点击主菜单中的“恢复默认设置”将会将所有设置恢复为默认值,但不会清空用户名和密码。</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">1. 点击“账号设置”按钮输入用户名和密码,用户名和密码将会被加密保存。</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">2. 点击使用网卡弹出框,选择认证通过的网络端口,一般情况下应选择“en0”。</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">3. “认证方式”选项可以选择认证方式,支持的有“锐捷私有”和“塞尔认证”。</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">4. DHCP方式用来指定获取IP地址的方式,默认为“认证后获取”,请根据自己学校的实际情况选择,一般应选择与官方客户端相同的选项,其中“二次认证”模式为获取到IP地址之后仍然会再次进行认证,以应对特殊情况。</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">5. 选择“忽略警告信息,继续进行认证”,认证将只会在不可排除的错误之时才会停止。</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">6. 选择自动登陆,将会在程序运行时自动登陆。</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">三.开始认证</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">1. 点击“开始认证”菜单项可以开始进行认证。此时程序图标将会发生改变,当程序认证结束,图标将会恢复正常状态。第一次认证时,将会要求输入本机的管理员账号和密码,请输入正确的密码以授予CocoaMento管理员权限用于认证。</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">2. 点击“断开连接”菜单项,即可断开认证。</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">3. 直接点击“退出程序”,将会询问是否退出认证。</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">4. 运行时请确认没有重复运行本程序,否则程序将会弹出警告提示。</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">5. 认证前请确认没有其他版本的Mentohust正在运行,否则程序将会弹出警告提示。</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">6. 如果找不到正在运行的CocoaMento或者Mentohust,请尝试在终端中输入:</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; color:#292462;"> killAll CocoaMento</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; color:#292462;"> sudo mentohust -k</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;"> 结束对应程序。</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">四.其他</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">1. 点击“显示日志”将会显示认证过程中的由Mentohust输入的信息细节,如遇到不可知的问题,请在认证时查看此日志信息以了解问题原因。</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">2. 点击“关于 CocoaMento”将会显示程序的版权信息。</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">3. 点击“使用说明”将会显示本帮助文档。</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">4. 点击"退出"即可退出本程序。</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p></body></html>
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CocoaMento-Src/main.cpp b/CocoaMento-Src/main.cpp
new file mode 100644
index 0000000..58ad831
--- /dev/null
+++ b/CocoaMento-Src/main.cpp
@@ -0,0 +1,24 @@
+#include
+#include "mento.h"
+#include "cocoaappinitlizer.h"
+#include
+
+
+
+
+
+
+int main(int argc, char *argv[])
+{
+ CocoaInitialize::initCocoaApp();
+ QApplication a(argc, argv);
+ QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF8"));
+ QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF8"));
+ QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF8"));
+ Mento m;
+ if(m.initSuccess())
+ return a.exec();
+ a.exit();
+
+ return CocoaInitialize::exitCocoaApp();;
+}
diff --git a/CocoaMento-Src/mento.cpp b/CocoaMento-Src/mento.cpp
new file mode 100644
index 0000000..63de6cd
--- /dev/null
+++ b/CocoaMento-Src/mento.cpp
@@ -0,0 +1,221 @@
+#include "mento.h"
+
+
+
+Mento::Mento(QObject *parent) :
+ QObject(parent)
+{
+ if(CocoaInitialize::DefaultApp()->checkRunning())
+ {
+ initsuccess=false;
+ QMessageBox::warning(0,"Warning","Cocoa Mento 正在运行当中!",QMessageBox::Ok,QMessageBox::Ok);
+ return;
+ }
+ else initsuccess=true;
+
+ log=new QTextBrowser();
+ log->setWindowModality(Qt::WindowModal);
+ log->setWindowFlags(Qt::WindowStaysOnTopHint|Qt::CustomizeWindowHint|Qt::WindowCloseButtonHint);
+ log->setGeometry(200,200,400,500);
+ log->setWindowTitle(tr("认证日志"));
+
+ gt=new Guite();
+
+ main=new Menu("Cocoa Mento");
+ sub=new Menu("Settings");
+
+ status=new MenuItem("[状态:正常] 未连接");
+ connectHandle=new MenuItem("开始认证");
+ settings=new MenuItem("偏好设置");
+ about=new MenuItem("关于CocoaMento");
+ aboutQt=new MenuItem("关于Qt");
+ help=new MenuItem("使用说明");
+ exit=new MenuItem("退出");
+ resetsettings=new MenuItem("重置偏好设置");
+ logs=new MenuItem("显示日志");
+
+ cv=new ConfigView();
+ cvcontainer=new MenuViewItem("Settings",cv);
+
+ cv->setPalette(Qt::white);
+ cv->show();
+
+ settings->setSubMenu(sub);
+
+ main->addMenuItem(status);
+ main->addMenuSeparator();
+ main->addMenuItem(connectHandle);
+ main->addMenuItem(settings);
+ main->addMenuItem(resetsettings);
+ main->addMenuItem(logs);
+ main->addMenuSeparator();
+ main->addMenuItem(help);
+ main->addMenuItem(about);
+ main->addMenuItem(aboutQt);
+ main->addMenuSeparator();
+ main->addMenuItem(exit);
+
+ sub->addMenuItem(cvcontainer);
+
+ icon=new StatusIcon();
+ icon->setMenu(main);
+ icon->showIcon();
+
+ mainthread=new MentoThread(cv->Config());
+
+ connect((QObject*)exit->port,SIGNAL(trigger()),this,SLOT(quitApp()));
+ connect((QObject*)resetsettings->port,SIGNAL(trigger()),cv,SLOT(resetConfig()));
+ connect((QObject*)connectHandle->port,SIGNAL(trigger()),this,SLOT(toggleConnect()));
+ connect((QObject*)logs->port,SIGNAL(trigger()),log,SLOT(show()));
+ connect((QObject*)about->port,SIGNAL(trigger()),gt,SLOT(showAbout()));
+ connect((QObject*)aboutQt->port,SIGNAL(trigger()),this,SLOT(showAboutQt()));
+ connect((QObject*)help->port,SIGNAL(trigger()),gt,SLOT(showHelp()));
+
+
+ connect(mainthread,SIGNAL(output(QString)),this,SLOT(outputHandle(QString)));
+ connect(mainthread,SIGNAL(exitSuccess()),this,SLOT(exitHandle()));
+ connect(mainthread,SIGNAL(statusChanged(QString,int)),this,SLOT(statusHandle(QString,int)));
+ connect(mainthread,SIGNAL(error(QString)),this,SLOT(errorHandle(QString)));
+ connect(mainthread,SIGNAL(authError()),this,SLOT(authMento()));
+ connect(mainthread,SIGNAL(noConfig()),this,SLOT(noconfigHandle()));
+ connect(mainthread,SIGNAL(notify(QString)),this,SLOT(notifyHandle(QString)));
+
+ if(cv->autoConnect()) toggleConnect();
+}
+
+void Mento::noconfigHandle()
+{
+ QMessageBox::critical(0,tr("配置信息不全!"),tr("用户名密码、认证使用网卡等信息未设置,连接无法继续。\n请仔细阅读使用说明,对认证信息进行正确配置!"),QMessageBox::Ok,QMessageBox::NoButton);
+ gt->showHelp();
+}
+
+void Mento::exitHandle()
+{
+ CocoaInitialize::growl("CocoaMento","链接已断开");
+ status->setTitle("[状态:正常] 连接已断开");
+ connectHandle->setTitle("开始认证");
+ icon->setIcon("normal.png");
+}
+
+void Mento::notifyHandle(QString str)
+{
+ CocoaInitialize::growl("CocoaMento",str.toUtf8().data());
+}
+
+void Mento::statusHandle(QString str, int status)
+{
+ if(status==0||status==2){
+ this->status->setTitle(tr("[状态:正常] %1").arg(str).toUtf8().data());
+ if(cv->growlStatus()) CocoaInitialize::growl("CocoaMento",str.toUtf8().data());
+ icon->setIcon((status==2)?"normal.png":"connecting.png");
+ }
+ else
+ {
+ this->status->setTitle(tr("[状态:警告] %1").arg(str).toUtf8().data());
+ icon->setIcon("warning.png");
+ }
+}
+
+void Mento::errorHandle(QString detail)
+{
+ mainthread->terminate();
+ icon->setIcon("critical.png");
+ QMessageBox::critical(0,tr("错误!"),tr("Mentohust 遇到严重错误,已经终止认证!\n\n错误细节: %1").arg(detail),QMessageBox::Ok,QMessageBox::Ok);
+}
+
+void Mento::toggleConnect()
+{
+ if(mainthread->isRunning())
+ {
+ mainthread->terminate();
+
+ }
+ else
+ {
+ status->setTitle("[状态:正常] 正在链接...");
+ connectHandle->setTitle("退出认证");
+ log->setTextColor(Qt::red);
+ log->setFontItalic(true);
+ log->append("\n\n");
+ log->append(QDateTime::currentDateTime().toString());
+
+ log->setTextColor(Qt::black);
+ mainthread->start();
+
+ }
+
+}
+
+void Mento::outputHandle(QString str)
+{
+ log->append(str);
+
+ qDebug()<isRunning())
+ {
+
+ if(QMessageBox::Ok==QMessageBox::warning(
+ 0,
+ tr("警告"),tr("Mentohust 正在运行,要退出认证么?"),
+ QMessageBox::Ok|QMessageBox::Cancel,QMessageBox::Ok))
+ mainthread->terminate();
+ else return;
+ }
+ cv->close();
+ log->close();
+ gt->close();
+}
+bool Mento::initSuccess()
+{
+ return initsuccess;
+}
+
+void Mento::authMento()
+{
+
+ icon->setIcon("warning.png");
+ mainthread->terminate();
+ if(CocoaInitialize::auth()==1)mainthread->start();
+ else
+ {
+ icon->setIcon("critical.png");
+ QMessageBox::warning(0,tr("获取权限失败"),tr("获取权限失败,认证无法继续,请正确授予 Cocoa Mento 系统权限!"));
+ this->connectHandle->setTitle("开始连接");
+ icon->setIcon("normal.png");
+ }
+}
+void Mento::showAboutQt()
+{
+ QMessageBox::aboutQt(0);
+}
+
+Mento::~Mento()
+{
+ if(initsuccess)
+ {
+ cv->deleteLater();
+ mainthread->deleteLater();
+ gt->deleteLater();
+ delete logs;
+ delete main;
+ delete sub;
+ delete status;
+ delete settings;
+ delete about;
+ delete aboutQt;
+ delete help;
+ delete exit;
+ delete cvcontainer;
+ delete icon;
+ delete resetsettings;
+ delete connectHandle;
+
+ }
+}
+
+
+
diff --git a/CocoaMento-Src/mento.h b/CocoaMento-Src/mento.h
new file mode 100644
index 0000000..3af2763
--- /dev/null
+++ b/CocoaMento-Src/mento.h
@@ -0,0 +1,76 @@
+#ifndef MENTO_H
+#define MENTO_H
+
+#define SETTINGS_PATH "/Contents/Resources/mento.conf"
+
+#include
+#include
+#include
+#include
+
+
+
+#include "configview.h"
+#include "StatusIcon.h"
+#include "menu.h"
+#include "menuitem.h"
+#include "menuviewitem.h"
+#include "cocoaappinitlizer.h"
+#include "mentothread.h"
+#include "guite.h"
+
+#define SERVICE_NAME "com.mycompany.cocoamento"
+
+class Mento : public QObject
+{
+ Q_OBJECT
+public:
+ explicit Mento(QObject *parent = 0);
+ bool initSuccess();
+ ~Mento();
+
+public slots:
+ void quitApp();
+ void toggleConnect();
+ void outputHandle(QString str);
+ void exitHandle();
+ void statusHandle(QString str,int status);
+ void errorHandle(QString detail);
+ void authMento();
+ void noconfigHandle();
+ void showAboutQt();
+ void notifyHandle(QString str);
+private:
+
+ bool initsuccess;
+
+
+ StatusIcon* icon;
+
+ Menu* main;
+ Menu* sub;
+
+ MenuViewItem* configview;
+
+ MenuItem* status;
+ MenuItem* connectHandle;
+ MenuItem* settings;
+ MenuItem* resetsettings;
+ MenuItem* logs;
+ MenuItem* about;
+ MenuItem* aboutQt;
+ MenuItem* help;
+ MenuItem* exit;
+
+ MenuViewItem* cvcontainer;
+
+ ConfigView* cv;
+ MentoThread * mainthread;
+ Guite* gt;
+
+ QTextBrowser * log;
+
+
+};
+
+#endif // MENTO_H
diff --git a/CocoaMento-Src/mentohust-src/Makefile b/CocoaMento-Src/mentohust-src/Makefile
new file mode 100644
index 0000000..b997eeb
--- /dev/null
+++ b/CocoaMento-Src/mentohust-src/Makefile
@@ -0,0 +1,10 @@
+mentohust: mentohust.o myini.o md5.o mycheck.o dlfunc.o myfunc.o mystate.o myconfig.o
+ llvm-gcc -o $@ $^ -liconv
+mentohust.o: mentohust.c myconfig.h mystate.h myfunc.h dlfunc.h
+ llvm-gcc -c $<
+dlfunc.o: dlfunc.c
+ llvm-gcc -c $<
+myfunc.o: myfunc.c md5.h mycheck.h
+ llvm-gcc -c $<
+..c.o:
+ llvm-gcc -c $<
diff --git a/CocoaMento-Src/mentohust-src/Makefile.am b/CocoaMento-Src/mentohust-src/Makefile.am
new file mode 100644
index 0000000..d158e9c
--- /dev/null
+++ b/CocoaMento-Src/mentohust-src/Makefile.am
@@ -0,0 +1,12 @@
+bin_PROGRAMS = mentohust
+
+sysconfdir = /etc
+
+dist_sysconf_DATA = mentohust.conf
+
+mentohust_SOURCES = myini.c md5.c mycheck.c dlfunc.c myfunc.c mystate.c myconfig.c mentohust.c
+
+mentohust_SOURCES += types.h myini.h md5.h mycheck.h dlfunc.h myfunc.h mystate.h myconfig.h
+
+mentohust_LDADD = $(LDADD)
+
diff --git a/CocoaMento-Src/mentohust-src/Makefile.in b/CocoaMento-Src/mentohust-src/Makefile.in
new file mode 100644
index 0000000..ce2ca41
--- /dev/null
+++ b/CocoaMento-Src/mentohust-src/Makefile.in
@@ -0,0 +1,519 @@
+# Makefile.in generated by automake 1.11 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = mentohust$(EXEEXT)
+subdir = src
+DIST_COMMON = $(dist_sysconf_DATA) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sysconfdir)"
+PROGRAMS = $(bin_PROGRAMS)
+am_mentohust_OBJECTS = myini.$(OBJEXT) md5.$(OBJEXT) mycheck.$(OBJEXT) \
+ dlfunc.$(OBJEXT) myfunc.$(OBJEXT) mystate.$(OBJEXT) \
+ myconfig.$(OBJEXT) mentohust.$(OBJEXT)
+mentohust_OBJECTS = $(am_mentohust_OBJECTS)
+am__DEPENDENCIES_1 =
+mentohust_DEPENDENCIES = $(am__DEPENDENCIES_1)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(mentohust_SOURCES)
+DIST_SOURCES = $(mentohust_SOURCES)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+DATA = $(dist_sysconf_DATA)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDADD = @LDADD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = /etc
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+dist_sysconf_DATA = mentohust.conf
+mentohust_SOURCES = myini.c md5.c mycheck.c dlfunc.c myfunc.c \
+ mystate.c myconfig.c mentohust.c types.h myini.h md5.h \
+ mycheck.h dlfunc.h myfunc.h mystate.h myconfig.h
+mentohust_LDADD = $(LDADD)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+mentohust$(EXEEXT): $(mentohust_OBJECTS) $(mentohust_DEPENDENCIES)
+ @rm -f mentohust$(EXEEXT)
+ $(LINK) $(mentohust_OBJECTS) $(mentohust_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dlfunc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mentohust.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mycheck.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/myconfig.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/myfunc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/myini.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mystate.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+install-dist_sysconfDATA: $(dist_sysconf_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(sysconfdir)" || $(MKDIR_P) "$(DESTDIR)$(sysconfdir)"
+ @list='$(dist_sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sysconfdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(sysconfdir)" || exit $$?; \
+ done
+
+uninstall-dist_sysconfDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(sysconfdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(sysconfdir)" && rm -f $$files
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sysconfdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS install-dist_sysconfDATA
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-dist_sysconfDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+ clean-generic ctags distclean distclean-compile \
+ distclean-generic distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-binPROGRAMS \
+ install-data install-data-am install-dist_sysconfDATA \
+ install-dvi install-dvi-am install-exec install-exec-am \
+ install-html install-html-am install-info install-info-am \
+ install-man install-pdf install-pdf-am install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \
+ ps ps-am tags uninstall uninstall-am uninstall-binPROGRAMS \
+ uninstall-dist_sysconfDATA
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/CocoaMento-Src/mentohust-src/auth.c b/CocoaMento-Src/mentohust-src/auth.c
new file mode 100644
index 0000000..9a94759
--- /dev/null
+++ b/CocoaMento-Src/mentohust-src/auth.c
@@ -0,0 +1,24 @@
+#include
+#include
+#include
+
+int main(int argc, const char *argv[])
+{
+ char path[100]={0};
+ strncpy(path,argv[0],strlen(argv[0])-4);
+ char mento[200]="chown root ";
+ char chmod[200]="chmod 4577 ";
+ char dylib[200]="chmod 777 ";
+ strcat(mento,path);
+ strcat(dylib,path);
+ strcat(chmod,path);
+
+ printf("%s\n",chmod);
+ strcat(mento,"mentohust");
+ strcat(chmod,"mentohust");
+
+ printf("%s\n",dylib);
+ strcat(dylib,"../Frameworks/mypcap.dylib");
+ if(system(mento)==0 && system(chmod)==0 &&system(dylib)==0 )return 0;
+ return 1;
+}
diff --git a/CocoaMento-Src/mentohust-src/dlfunc.c b/CocoaMento-Src/mentohust-src/dlfunc.c
new file mode 100644
index 0000000..f1c2be2
--- /dev/null
+++ b/CocoaMento-Src/mentohust-src/dlfunc.c
@@ -0,0 +1,147 @@
+/* -*- Mode: C; tab-width: 4; -*- */
+/*
+* Copyright (C) 2009, HustMoon Studio
+*
+* 文件名称:dlfunc.c
+* 摘 要:动态载入库函数
+* 作 者:HustMoon@BYHH
+* 邮 箱:www.ehust@gmail.com
+* 日 期:2009.11.11
+*/
+#include "dlfunc.h"
+#ifndef NO_DYLOAD
+#include
+
+
+int (*pcap_findalldevs)(pcap_if_t **, char *);
+void (*pcap_freealldevs)(pcap_if_t *);
+pcap_t *(*pcap_open_live)(const char *, int, int, int, char *);
+int (*pcap_compile)(pcap_t *, struct bpf_program *, const char *, int, bpf_u_int32);
+int (*pcap_setfilter)(pcap_t *, struct bpf_program *);
+char *(*pcap_geterr)(pcap_t *);
+void (*pcap_freecode)(struct bpf_program *);
+int (*pcap_loop)(pcap_t *, int, pcap_handler, unsigned char *);
+void (*pcap_close)(pcap_t *);
+void (*pcap_breakloop)(pcap_t *);
+int (*pcap_sendpacket)(pcap_t *, const unsigned char *, int);
+
+static void *libpcap = NULL;
+
+int load_libpcap(void) {
+ char *error;
+ char *file[] = {"../Frameworks/mypcap.dylib"};
+ int i, count =1 ;
+ for (i=0; i
+
+typedef void NotifyNotification, GtkWidget, GError;
+typedef char gchar;
+typedef int gint, gboolean;
+
+static gboolean (*notify_notification_update)(NotifyNotification *, const gchar *,
+ const gchar *, const gchar *);
+static void (*notify_notification_set_timeout)(NotifyNotification *, gint);
+static gboolean (*notify_notification_show)(NotifyNotification *, GError **);
+
+static void *libnotify = NULL;
+static NotifyNotification *notify = NULL;
+
+int load_libnotify(void) {
+ char *error;
+ gboolean (*notify_init)(const char *);
+ NotifyNotification *(*notify_notification_new)(const gchar *, const gchar *,
+ const gchar *, GtkWidget *);
+#ifdef MAC_OS
+ char *file[] = {"libnotify.dylib", "libnotify.1.dylib"};
+ int i, count = 2;
+#else
+ char *file[] = {"libnotify.so", "libnotify.so.1"};
+ int i, count = 2;
+#endif
+ for (i=0; i
+#include
+#include
+#include
+
+
+#define PCAP_ERRBUF_SIZE 256
+#define PCAP_IF_LOOPBACK 0x00000001
+#define NO_NOTIFY
+
+typedef unsigned int bpf_u_int32;
+typedef void pcap_t;
+typedef struct pcap_if {
+ struct pcap_if *next;
+ char *name;
+ char *description;
+ void *addresses;
+ bpf_u_int32 flags;
+}pcap_if_t;
+struct bpf_program {
+ unsigned int bf_len;
+ void *bf_insns;
+};
+struct pcap_pkthdr {
+ struct timeval ts;
+ bpf_u_int32 caplen;
+ bpf_u_int32 len;
+};
+typedef void (*pcap_handler)(unsigned char *, const struct pcap_pkthdr *, const unsigned char *);
+
+#ifdef NO_DYLOAD
+int pcap_findalldevs(pcap_if_t **, char *);
+void pcap_freealldevs(pcap_if_t *);
+pcap_t *pcap_open_live(const char *, int, int, int, char *);
+int pcap_compile(pcap_t *, struct bpf_program *, const char *, int, bpf_u_int32);
+int pcap_setfilter(pcap_t *, struct bpf_program *);
+char *pcap_geterr(pcap_t *);
+void pcap_freecode(struct bpf_program *);
+int pcap_loop(pcap_t *, int, pcap_handler, unsigned char *);
+void pcap_close(pcap_t *);
+void pcap_breakloop(pcap_t *);
+int pcap_sendpacket(pcap_t *, const unsigned char *, int);
+
+#else
+extern int (*pcap_findalldevs)(pcap_if_t **, char *);
+extern void (*pcap_freealldevs)(pcap_if_t *);
+extern pcap_t *(*pcap_open_live)(const char *, int, int, int, char *);
+extern int (*pcap_compile)(pcap_t *, struct bpf_program *, const char *, int, bpf_u_int32);
+extern int (*pcap_setfilter)(pcap_t *, struct bpf_program *);
+extern char *(*pcap_geterr)(pcap_t *);
+extern void (*pcap_freecode)(struct bpf_program *);
+extern int (*pcap_loop)(pcap_t *, int, pcap_handler, unsigned char *);
+extern void (*pcap_close)(pcap_t *);
+extern void (*pcap_breakloop)(pcap_t *);
+extern int (*pcap_sendpacket)(pcap_t *, const unsigned char *, int);
+
+int load_libpcap(void); /* 载入libpcap.so */
+void free_libpcap(void); /* 释放libpcap.so */
+
+#endif /* NO_DYLOAD */
+
+#ifndef NO_NOTIFY
+int load_libnotify(void); /* 载入libnotify.so */
+void free_libnotify(void); /* 释放libnotify.so */
+void set_timeout(int timeout); /* 设置超时间隔 */
+void show_notify(const char *summary, char *body); /* 显示通知:概要、正文 */
+#endif /* NO_NOTIFY */
+
+
+void setPcapPath(char ap[100]);
+
+#endif /* HUSTMOON_DLFUNC_H */
+
diff --git a/CocoaMento-Src/mentohust-src/md5.c b/CocoaMento-Src/mentohust-src/md5.c
new file mode 100644
index 0000000..074e988
--- /dev/null
+++ b/CocoaMento-Src/mentohust-src/md5.c
@@ -0,0 +1,297 @@
+/* MD5.c - an implementation of md5 algorithm */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+#include "md5.h"
+#include
+
+/* Constants for MD5Transform routine. */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+static void MD5Transform(UINT4 [4], UCHAR [64]);
+static void Encode(UCHAR *, UINT4 *, UINT4);
+static void Decode(UINT4 *, UCHAR *, UINT4);
+
+static UCHAR PADDING[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context.
+ */
+void MD5Init (MD5_CTX * context)
+
+{
+ context->count[0] = context->count[1] = 0;
+ /* Load magic initialization constants.
+*/
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xefcdab89;
+ context->state[2] = 0x98badcfe;
+ context->state[3] = 0x10325476;
+}
+
+/* MD5 block update operation. Continues an MD5 message-digest
+ operation, processing another message block, and updating the
+ context.
+ */
+void MD5Update (MD5_CTX *context, UCHAR *input, UINT4 inputLen)
+
+{
+ UINT4 i, index, partLen;
+
+ /* Compute number of bytes mod 64 */
+ index = (UINT4)((context->count[0] >> 3) & 0x3F);
+
+ /* Update number of bits */
+ if ((context->count[0] += ((UINT4)inputLen << 3))
+ < ((UINT4)inputLen << 3))
+ context->count[1]++;
+ context->count[1] += ((UINT4)inputLen >> 29);
+
+ partLen = 64 - index;
+
+ /* Transform as many times as possible.
+*/
+ if (inputLen >= partLen) {
+ memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen);
+ MD5Transform (context->state, context->buffer);
+
+ for (i = partLen; i + 63 < inputLen; i += 64)
+ MD5Transform (context->state, &input[i]);
+
+ index = 0;
+ }
+ else
+ i = 0;
+
+ /* Buffer remaining input */
+ memcpy((POINTER)&context->buffer[index], (POINTER)&input[i],inputLen-i);
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+ the message digest and zeroizing the context.
+ */
+void MD5Final (UCHAR digest[16], MD5_CTX *context)
+{
+ UCHAR bits[8];
+ UINT4 index, padLen;
+
+ /* Save number of bits */
+ Encode (bits, context->count, 8);
+
+ /* Pad out to 56 mod 64.
+*/
+ index = (UINT4)((context->count[0] >> 3) & 0x3f);
+ padLen = (index < 56) ? (56 - index) : (120 - index);
+ MD5Update (context, PADDING, padLen);
+
+ /* Append length (before padding) */
+ MD5Update (context, bits, 8);
+
+ /* Store state in digest */
+ Encode (digest, context->state, 16);
+
+ /* Zeroize sensitive information.
+*/
+ memset ((POINTER)context, 0, sizeof (*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block.
+ */
+static void MD5Transform (UINT4 state[4],UCHAR block[64])
+{
+ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+ Decode (x, block, 64);
+
+ /* Round 1 */
+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+
+ /* Zeroize sensitive information.
+
+*/
+ memset ((POINTER)x, 0, sizeof (x));
+}
+
+/* Encodes input (UINT4) into output (UCHAR). Assumes len is
+ a multiple of 4.
+ */
+static void Encode (UCHAR *output, UINT4 *input, UINT4 len)
+{
+ UINT4 i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4) {
+ output[j] = (UCHAR)(input[i] & 0xff);
+ output[j+1] = (UCHAR)((input[i] >> 8) & 0xff);
+ output[j+2] = (UCHAR)((input[i] >> 16) & 0xff);
+ output[j+3] = (UCHAR)((input[i] >> 24) & 0xff);
+ }
+}
+
+/* Decodes input (UCHAR) into output (UINT4). Assumes len is
+ a multiple of 4.
+ */
+static void Decode (UINT4 *output, UCHAR *input, UINT4 len)
+{
+ UINT4 i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4)
+ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
+ (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
+}
+
+/*Compute the md5sum (return static-local-variable),whose length is 16 bytes.*/
+UCHAR* ComputeHash(UCHAR* src, UINT4 len)
+{
+ MD5_CTX context;
+ static UCHAR digest[16];
+ MD5Init(&context);
+ MD5Update(&context, src, len);
+ MD5Final(digest, &context);
+ return digest;
+}
diff --git a/CocoaMento-Src/mentohust-src/md5.h b/CocoaMento-Src/mentohust-src/md5.h
new file mode 100644
index 0000000..7b29a7c
--- /dev/null
+++ b/CocoaMento-Src/mentohust-src/md5.h
@@ -0,0 +1,43 @@
+/* MD5.H - header file for MD5.C */
+
+/*
+Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.*/
+
+#ifndef MD5_H
+#define MD5_H
+#include "types.h"
+
+/* MD5 context. */
+typedef struct
+{
+ UINT4 state[4]; /* state (ABCD) */
+ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
+ UCHAR buffer[64]; /* input buffer */
+} MD5_CTX;
+
+void MD5Init(MD5_CTX * context);
+void MD5Update(MD5_CTX *context, UCHAR *input, UINT4 inputLen);
+void MD5Final(UCHAR digest[16], MD5_CTX *context);
+
+UCHAR* ComputeHash(UCHAR *src, UINT4 len);
+
+#endif /* MD5_H */
diff --git a/CocoaMento-Src/mentohust-src/mentohust.c b/CocoaMento-Src/mentohust-src/mentohust.c
new file mode 100644
index 0000000..8759097
--- /dev/null
+++ b/CocoaMento-Src/mentohust-src/mentohust.c
@@ -0,0 +1,309 @@
+/* -*- Mode: C; tab-width: 4; -*- */
+/*
+* Copyright (C) 2009, HustMoon Studio
+*
+* 文件名称:mentohust.c
+* 摘 要:MentoHUST主函数
+* 作 者:HustMoon@BYHH
+* 邮 箱:www.ehust@gmail.com
+*/
+
+#define MAC_OS
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#else
+#define HAVE_ICONV_H
+#endif
+
+
+
+#include "myconfig.h"
+#include "mystate.h"
+#include "myfunc.h"
+#include "dlfunc.h"
+#include
+#include
+#include
+#include
+#include
+
+//#ifdef HAVE_ICONV_H
+#include
+//#endif
+
+#define NO_NOTIFY
+
+extern pcap_t *hPcap;
+extern volatile int state;
+extern u_char *fillBuf;
+extern const u_char *capBuf;
+extern unsigned startMode, dhcpMode, maxFail;
+extern u_char destMAC[];
+extern int lockfd;
+#ifndef NO_NOTIFY
+extern int showNotify;
+#endif
+#ifndef NO_ARP
+extern u_int32_t rip, gateway;
+extern u_char gateMAC[];
+#endif
+
+
+static void exit_handle(void); /* 退出回调 */
+static void sig_handle(int sig); /* 信号回调 */
+static void pcap_handle(u_char *user, const struct pcap_pkthdr *h, const u_char *buf); /* pcap_loop回调 */
+static void showRuijieMsg(const u_char *buf, unsigned bufLen); /* 显示锐捷服务器提示信息 */
+static void showCernetMsg(const u_char *buf); /* 显示赛尔服务器提示信息 */
+
+
+int main(int argc, char **argv)
+{
+
+ atexit(exit_handle);
+
+ if(initConfig(argc, argv))
+ exit(EXIT_FAILURE);
+ signal(SIGALRM, sig_handle); /* 定时器 */
+ signal(SIGHUP, sig_handle); /* 注销时 */
+ signal(SIGINT, sig_handle); /* Ctrl+C */
+ signal(SIGQUIT, sig_handle); /* Ctrl+\ */
+ signal(SIGTSTP, sig_handle); /* Ctrl+Z */
+ signal(SIGTERM, sig_handle); /* 被结束时 */
+ signal(SIGKILL, sig_handle);
+
+
+ if (dhcpMode == 3) /* 认证前DHCP */
+ switchState(ID_DHCP);
+ else
+ switchState(ID_START); /* 开始认证 */
+ if (-1 == pcap_loop(hPcap, -1, pcap_handle, NULL)) { /* 开始捕获数据包 */
+ printf("!! 捕获数据包失败,请检查网络连接!\n");
+#ifndef NO_NOTIFY
+ if (showNotify)
+ show_notify("MentoHUST - 错误提示", "捕获数据包失败,请检查网络连接!");
+#endif
+ }
+ exit(EXIT_FAILURE);
+}
+
+static void exit_handle(void)
+{
+ if (state != ID_DISCONNECT)
+ switchState(ID_DISCONNECT);
+ if (hPcap != NULL)
+ pcap_close(hPcap);
+ if (fillBuf != NULL)
+ free(fillBuf);
+ if (lockfd > -1)
+ close(lockfd);
+#ifndef NO_NOTIFY
+ free_libnotify();
+#endif
+#ifndef NO_DYLOAD
+ free_libpcap();
+#endif
+ printf(">! 认证已退出。\n");
+ fflush(stdout);
+}
+
+static void sig_handle(int sig)
+{
+ if (sig == SIGALRM) /* 定时器 */
+ {
+ if (-1 == switchState(state))
+ {
+ pcap_breakloop(hPcap);
+ printf("!! 发送数据包失败, 请检查网络连接!\n");
+ fflush(stdout);
+#ifndef NO_NOTIFY
+ if (showNotify)
+ show_notify("MentoHUST - 错误提示", "发送数据包失败, 请检查网络连接!");
+#endif
+ exit(EXIT_FAILURE);
+ }
+ }
+ else /* 退出 */
+ {
+ pcap_breakloop(hPcap);
+ exit(EXIT_SUCCESS);
+ }
+}
+
+static void pcap_handle(u_char *user, const struct pcap_pkthdr *h, const u_char *buf)
+{
+ static unsigned failCount = 0;
+#ifndef NO_ARP
+ if (buf[0x0c]==0x88 && buf[0x0d]==0x8e) {
+#endif
+ if (memcmp(destMAC, buf+6, 6)!=0 && startMode>2) /* 服务器MAC地址不符 */
+ return;
+ capBuf = buf;
+ if (buf[0x0F]==0x00 && buf[0x12]==0x01 && buf[0x16]==0x01) { /* 验证用户名 */
+ if (startMode < 3) {
+ memcpy(destMAC, buf+6, 6);
+ printf("** 认证MAC:\t%s\n", formatHex(destMAC, 6));
+ startMode += 3; /* 标记为已获取 */
+ }
+ if (startMode==3 && memcmp(buf+0x17, "User name", 9)==0) /* 塞尔 */
+ startMode = 5;
+ switchState(ID_IDENTITY);
+ }
+ else if (buf[0x0F]==0x00 && buf[0x12]==0x01 && buf[0x16]==0x04) /* 验证密码 */
+ switchState(ID_CHALLENGE);
+ else if (buf[0x0F]==0x00 && buf[0x12]==0x03) { /* 认证成功 */
+ printf(">> 认证成功!\n");
+ fflush(stdout);
+ failCount = 0;
+ if (!(startMode%3 == 2)) {
+ getEchoKey(buf);
+ showRuijieMsg(buf, h->caplen);
+ }
+ if (dhcpMode==1 || dhcpMode==2) /* 二次认证第一次或者认证后 */
+ switchState(ID_DHCP);
+ else if (startMode%3 == 2)
+ switchState(ID_WAITECHO);
+ else
+ switchState(ID_ECHO);
+ }
+ else if (buf[0x0F]==0x00 && buf[0x12]==0x01 && buf[0x16]==0x02) /* 显示赛尔提示信息 */
+ showCernetMsg(buf);
+ else if (buf[0x0F] == 0x05) /* (赛尔)响应在线 */
+ switchState(ID_ECHO);
+ else if (buf[0x0F]==0x00 && buf[0x12]==0x04) { /* 认证失败或被踢下线 */
+ if (state==ID_WAITECHO || state==ID_ECHO) {
+ printf(">! 认证掉线,开始重连!\n");
+ fflush(stdout);
+ switchState(ID_START);
+ }
+ else if (buf[0x1b]!=0 || startMode%3==2) {
+ printf("!! 认证失败!\n");
+ fflush(stdout);
+ if (startMode%3 != 2)
+ showRuijieMsg(buf, h->caplen);
+ if (maxFail && ++failCount>=maxFail) {
+ printf(">! 连续认证失败%u次,退出认证。\n", maxFail);
+ fflush(stdout);
+ exit(EXIT_SUCCESS);
+ }
+ restart();
+ }
+ else
+ switchState(ID_START);
+ }
+#ifndef NO_ARP
+ } else if (gateMAC[0]!=0xFE && buf[0x0c]==0x08 && buf[0x0d]==0x06) {
+ if (*(u_int32_t *)(buf+0x1c) == gateway) {
+ char str[50];
+ if (gateMAC[0] == 0xFF) {
+ memcpy(gateMAC, buf+0x16, 6);
+ printf("** 网关MAC:\t%s\n", formatHex(gateMAC, 6));
+ fflush(stdout);
+ sprintf(str, "arp -s %s %s", formatIP(gateway), formatHex(gateMAC, 6));
+ system(str);
+ } else if (buf[0x15]==0x02 && *(u_int32_t *)(buf+0x26)==rip
+ && memcmp(gateMAC, buf+0x16, 6)!=0) {
+ printf("** ARP欺骗:\t%s\n", formatHex(buf+0x16, 6));
+ fflush(stdout);
+#ifndef NO_NOTIFY
+ if (showNotify) {
+ sprintf(str, "欺骗源: %s", formatHex(buf+0x16, 6));
+ show_notify("MentoHUST - ARP提示", str);
+ }
+#endif
+ }
+ }
+ }
+#endif
+}
+
+#ifndef MAC_OS
+static char *gbk2utf(char *src, size_t srclen) /* GBK转UTF-8 */
+#else
+static char *gbk2utf(const char *src, size_t srclen) /* GBK转UTF-8 */
+#endif
+{
+#ifdef HAVE_ICONV_H
+ /* GBK一汉字俩字节,UTF-8一汉字3字节,二者ASCII字符均一字节
+ 所以这样申请是足够的了,要记得释放 */
+ size_t dstlen = srclen * 3 / 2 + 1;
+ size_t left = dstlen;
+ char *dst, *pdst;
+ int res;
+ iconv_t cd = iconv_open("utf-8", "gbk");
+ if (cd == (iconv_t)-1)
+ return NULL;
+ dst = (char *)malloc(dstlen);
+ pdst = dst;
+ res = iconv(cd, &src, &srclen, &pdst, &left);
+ iconv_close(cd);
+ if (res == -1)
+ {
+ free(dst);
+ return NULL;
+ }
+ dst[dstlen-left] = '\0';
+#else
+ char *dst = (char *)malloc(srclen+1);
+ memcpy(dst, src, srclen);
+ dst[srclen] = '\0';
+#endif
+ return dst;
+}
+
+static void showRuijieMsg(const u_char *buf, unsigned bufLen)
+{
+ char *serverMsg;
+ int length = buf[0x1b];
+ if (length > 0)
+ {
+ for (serverMsg=(char *)(buf+0x1c); *serverMsg=='\r'||*serverMsg=='\n'; serverMsg++,length--); /* 跳过开头的换行符 */
+ if (strlen(serverMsg) < length)
+ length = strlen(serverMsg);
+ if (length>0 && (serverMsg=gbk2utf(serverMsg, length))!=NULL)
+ {
+ printf("$$ 系统提示:\t%s\n", serverMsg);
+#ifndef NO_NOTIFY
+ if (showNotify)
+ show_notify("MentoHUST - 系统提示", serverMsg);
+#endif
+ free(serverMsg);
+ }
+ }
+ if ((length=0x1c+buf[0x1b]+0x69+39) < bufLen)
+ {
+ serverMsg=(char *)(buf+length);
+ if (buf[length-1]-2 > bufLen-length)
+ length = bufLen - length;
+ else
+ length = buf[length-1]-2;
+ for (; *serverMsg=='\r'||*serverMsg=='\n'; serverMsg++,length--);
+ if (length>0 && (serverMsg=gbk2utf(serverMsg, length))!=NULL)
+ {
+ printf("$$ 计费提示:\t%s\n", serverMsg);
+#ifndef NO_NOTIFY
+ if (showNotify)
+ show_notify("MentoHUST - 计费提示", serverMsg);
+#endif
+ free(serverMsg);
+ }
+ }
+ fflush(stdout);
+}
+
+static void showCernetMsg(const u_char *buf)
+{
+ char *serverMsg = (char *)(buf+0x17);
+ int length = ntohs(*(u_int16_t *)(buf+0x14)) - 5;
+ if (strlen(serverMsg) < length)
+ length = strlen(serverMsg);
+ if (length>0 && (serverMsg=gbk2utf(serverMsg, length))!=NULL)
+ {
+ printf("$$ 系统提示:\t%s\n", serverMsg);
+#ifndef NO_NOTIFY
+ if (showNotify)
+ show_notify("MentoHUST - 系统提示", serverMsg);
+#endif
+ free(serverMsg);
+ }
+ fflush(stdout);
+}
diff --git a/CocoaMento-Src/mentohust-src/mycheck.c b/CocoaMento-Src/mentohust-src/mycheck.c
new file mode 100644
index 0000000..272d8c4
--- /dev/null
+++ b/CocoaMento-Src/mentohust-src/mycheck.c
@@ -0,0 +1,189 @@
+/* -*- Mode: C; tab-width: 4; -*- */
+/*
+* Copyright (C) 2009, HustMoon Studio
+*
+* 文件名称:mycheck.c
+* 摘 要:客户端校验算法
+* 作 者:kkHAIKE & HustMoon
+*/
+#include "mycheck.h"
+#include "md5.h"
+#include
+#include
+#include
+
+static BYTE *bin_8021x = NULL;
+static DWORD size_8021x;
+static BYTE hex[][17]={"0123456789ABCDEF", "0123456789abcdef"};
+
+#ifdef WORDS_BIGENDIAN
+WORD ltobs(WORD x) {
+ return ((x & 0xff) << 8) | ((x & 0xff00) >> 8);
+}
+
+DWORD ltobl(DWORD x) {
+ return ((x & 0xff) << 24) |\
+ ((x & 0xff00) << 8) |\
+ ((x & 0xff0000) >> 8) |\
+ ((x & 0xff000000) >> 24);
+}
+#endif
+
+void hex_to_str(const BYTE *a, char *b, int hexsize, int upper) {
+ BYTE *q = (BYTE *)b;
+ int i;
+ for (i=0; i>4]; q++;
+ *q = hex[upper][a[i]&0xf]; q++;
+ }
+ *q = 0;
+}
+
+BYTE *ReadCode(const char *file, DWORD *size) {
+ BYTE *data = NULL;
+ int i;
+ FILE *fp;
+ PPE_HEADER_MAP hpe;
+
+ if ((fp=fopen(file, "rb")) == NULL)
+ goto fileError;
+ data = (BYTE *)malloc(0x1000);
+ if (fread(data, 0x1000, 1, fp) < 1)
+ goto fileError;
+
+ hpe = (PPE_HEADER_MAP)(data + LTOBL(((PIMAGE_DOS_HEADER)data)->e_lfanew));
+ for (i=0; i_head.NumberOfSections); i++) {
+ if (LTOBL(hpe->section_header[i].Characteristics) & (IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_CODE)) {
+ fseek(fp, LTOBL(hpe->section_header[i].PointerToRawData), SEEK_SET);
+ *size = LTOBL(hpe->section_header[i].SizeOfRawData);
+ free(data);
+ data = (BYTE *)malloc(*size);
+ if (fread(data, *size, 1, fp) < 1)
+ goto fileError;
+ fclose(fp);
+ return data;
+ }
+ }
+
+fileError:
+ if (fp != NULL)
+ fclose(fp);
+ if (data != NULL)
+ free(data);
+ return NULL;
+}
+
+BYTE *ReadCode2(const char *dataFile, DWORD *size) {
+ BYTE Buf[16], *buf=Buf;
+ FILE *fp = NULL;
+ if ((fp=fopen(dataFile, "rb")) == NULL
+ || fread(buf, 16, 1, fp ) < 1)
+ goto fileError;
+ *size = LTOBL(*(UINT4 *)buf ^ *(UINT4 *)(buf + 4));
+ if ((int)*size <= 0)
+ goto fileError;
+ buf = (BYTE *)malloc(*size+0x100);
+ if (fread(buf, *size, 1, fp) < 1) {
+ free(buf);
+ goto fileError;
+ }
+ fclose(fp);
+ return buf;
+
+fileError:
+ if (fp != NULL)
+ fclose(fp);
+ return NULL;
+}
+
+void check_free() {
+ if (bin_8021x) {
+ free(bin_8021x);
+ bin_8021x = NULL;
+ }
+}
+
+int check_init(const char *dataFile) {
+ char name[0x100];
+ char *p;
+ check_free();
+ strcpy(name, dataFile);
+ if ((p=strrchr(name, '/')+1) == (void *)1)
+ p = name;
+ strcpy(p, "8021x.exe");
+ if ((bin_8021x=ReadCode(name, &size_8021x)) == NULL
+ && (bin_8021x=ReadCode2(dataFile, &size_8021x)) == NULL)
+ return -1;
+ return 0;
+}
+
+void V2_check(const BYTE *seed, char *final_str) {
+ int i, size = size_8021x / 8;
+ BYTE table[144], *md5Dig, *b8021x = (BYTE *)malloc(size+16);
+ memcpy(b8021x, seed, 16);
+ for (i=0; i<8; i++) {
+ memcpy(b8021x+16, bin_8021x+size*i, size);
+ md5Dig = ComputeHash(b8021x, size+16);
+ table[18*i] = seed[2*i];
+ memcpy(table+18*i+1, md5Dig, 16);
+ table[18*i+17] = seed[2*i+1];
+ }
+ free(b8021x);
+ md5Dig = ComputeHash(table, 144);
+ hex_to_str(md5Dig, final_str, 16, 1);
+}
+
+DWORD getVer(const char *file) {
+ FILE *fp;
+ BYTE *data = NULL;
+ int i, j;
+ DWORD size, VirtualAddress;
+ PPE_HEADER_MAP hpe;
+ PIMAGE_RESOURCE_DIRECTORY prd;
+ PIMAGE_RESOURCE_DATA_ENTRY prde;
+ PVS_VERSIONINFO pvs;
+
+ if ((fp=fopen(file, "rb")) == NULL)
+ goto fileError;
+ data = (BYTE *)malloc(0x1000);
+ if (fread(data, 0x1000, 1, fp) < 1)
+ goto fileError;
+
+ hpe = (PPE_HEADER_MAP)(data + LTOBL(((PIMAGE_DOS_HEADER)data)->e_lfanew));
+ for (i=LTOBS(hpe->_head.NumberOfSections)-1; i>=0; i--) {
+ if (strcmp(hpe->section_header[i].Name, ".rsrc") == 0) {
+ fseek(fp, LTOBL(hpe->section_header[i].PointerToRawData), SEEK_SET);
+ size = LTOBL(hpe->section_header[i].SizeOfRawData);
+ VirtualAddress = LTOBL(hpe->section_header[i].VirtualAddress);
+ free(data);
+ data = (BYTE *)malloc(size);
+ if (fread(data, size, 1, fp) < 1)
+ goto fileError;
+ prd = (PIMAGE_RESOURCE_DIRECTORY)data;
+ for (j=0; jNumberOfIdEntries); j++) {
+ prd->DirectoryEntries[j].Name = LTOBL(prd->DirectoryEntries[j].Name);
+ if (prd->DirectoryEntries[j].Id==16 && prd->DirectoryEntries[j].NameIsString==0) {
+ prd->DirectoryEntries[j].OffsetToData = LTOBL(prd->DirectoryEntries[j].OffsetToData);
+ prd = (PIMAGE_RESOURCE_DIRECTORY)(data+prd->DirectoryEntries[j].OffsetToDirectory);
+ prd->DirectoryEntries[0].OffsetToData = LTOBL(prd->DirectoryEntries[0].OffsetToData);
+ prd = (PIMAGE_RESOURCE_DIRECTORY)(data+prd->DirectoryEntries[0].OffsetToDirectory);
+ prde = (PIMAGE_RESOURCE_DATA_ENTRY)(data+LTOBL(prd->DirectoryEntries[0].OffsetToData));
+ pvs = (PVS_VERSIONINFO)(data+LTOBL(prde->OffsetToData)-VirtualAddress);
+ size = pvs->Value.dwFileVersionMS;
+ fclose(fp);
+ free(data);
+ return size;
+ }
+ }
+ goto fileError;
+ }
+ }
+
+fileError:
+ if (fp != NULL)
+ fclose(fp);
+ if (data != NULL)
+ free(data);
+ return -1;
+}
+
diff --git a/CocoaMento-Src/mentohust-src/mycheck.h b/CocoaMento-Src/mentohust-src/mycheck.h
new file mode 100644
index 0000000..eb25c7f
--- /dev/null
+++ b/CocoaMento-Src/mentohust-src/mycheck.h
@@ -0,0 +1,220 @@
+/* -*- Mode: C; tab-width: 4; -*- */
+/*
+* Copyright (C) 2009, HustMoon Studio
+*
+* 文件名称:mycheck.h
+* 摘 要:客户端校验算法
+* 作 者:kkHAIKE
+*/
+#ifndef MYCHECK_H
+#define MYCHECK_H
+
+#include "types.h"
+
+typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
+ WORD e_magic; // Magic number
+ WORD e_cblp; // Bytes on last page of file
+ WORD e_cp; // Pages in file
+ WORD e_crlc; // Relocations
+ WORD e_cparhdr; // Size of header in paragraphs
+ WORD e_minalloc; // Minimum extra paragraphs needed
+ WORD e_maxalloc; // Maximum extra paragraphs needed
+ WORD e_ss; // Initial (relative) SS value
+ WORD e_sp; // Initial SP value
+ WORD e_csum; // Checksum
+ WORD e_ip; // Initial IP value
+ WORD e_cs; // Initial (relative) CS value
+ WORD e_lfarlc; // File address of relocation table
+ WORD e_ovno; // Overlay number
+ WORD e_res[4]; // Reserved words
+ WORD e_oemid; // OEM identifier (for e_oeminfo)
+ WORD e_oeminfo; // OEM information; e_oemid specific
+ WORD e_res2[10]; // Reserved words
+ LONG e_lfanew; // File address of new exe header
+} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
+
+typedef struct _IMAGE_FILE_HEADER {
+ WORD Machine;
+ WORD NumberOfSections;
+ DWORD TimeDateStamp;
+ DWORD PointerToSymbolTable;
+ DWORD NumberOfSymbols;
+ WORD SizeOfOptionalHeader;
+ WORD Characteristics;
+} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
+
+typedef struct _IMAGE_DATA_DIRECTORY {
+ DWORD VirtualAddress;
+ DWORD Size;
+} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
+
+#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
+typedef struct _IMAGE_OPTIONAL_HEADER {
+ //
+ // Standard fields.
+ //
+
+ WORD Magic;
+ BYTE MajorLinkerVersion;
+ BYTE MinorLinkerVersion;
+ DWORD SizeOfCode;
+ DWORD SizeOfInitializedData;
+ DWORD SizeOfUninitializedData;
+ DWORD AddressOfEntryPoint;
+ DWORD BaseOfCode;
+ DWORD BaseOfData;
+
+ //
+ // NT additional fields.
+ //
+
+ DWORD ImageBase;
+ DWORD SectionAlignment;
+ DWORD FileAlignment;
+ WORD MajorOperatingSystemVersion;
+ WORD MinorOperatingSystemVersion;
+ WORD MajorImageVersion;
+ WORD MinorImageVersion;
+ WORD MajorSubsystemVersion;
+ WORD MinorSubsystemVersion;
+ DWORD Win32VersionValue;
+ DWORD SizeOfImage;
+ DWORD SizeOfHeaders;
+ DWORD CheckSum;
+ WORD Subsystem;
+ WORD DllCharacteristics;
+ DWORD SizeOfStackReserve;
+ DWORD SizeOfStackCommit;
+ DWORD SizeOfHeapReserve;
+ DWORD SizeOfHeapCommit;
+ DWORD LoaderFlags;
+ DWORD NumberOfRvaAndSizes;
+ IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
+} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
+
+#define IMAGE_SIZEOF_SHORT_NAME 8
+typedef struct _IMAGE_SECTION_HEADER {
+ char Name[IMAGE_SIZEOF_SHORT_NAME];
+ union {
+ DWORD PhysicalAddress;
+ DWORD VirtualSize;
+ } Misc;
+ DWORD VirtualAddress;
+ DWORD SizeOfRawData;
+ DWORD PointerToRawData;
+ DWORD PointerToRelocations;
+ DWORD PointerToLinenumbers;
+ WORD NumberOfRelocations;
+ WORD NumberOfLinenumbers;
+ DWORD Characteristics;
+} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
+
+typedef struct _PE_HEADER_MAP
+{
+ DWORD signature;
+ IMAGE_FILE_HEADER _head;
+ IMAGE_OPTIONAL_HEADER opt_head;
+ IMAGE_SECTION_HEADER section_header[8];
+}PE_HEADER_MAP,*PPE_HEADER_MAP;
+
+typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {
+#ifdef WORDS_BIGENDIAN
+ union {
+ struct {
+ DWORD NameIsString:1;
+ DWORD NameOffset:31;
+ };
+ DWORD Name;
+ struct {
+ WORD Id_unuse;
+ WORD Id;
+ };
+ };
+ union {
+ DWORD OffsetToData;
+ struct {
+ DWORD DataIsDirectory:1;
+ DWORD OffsetToDirectory:31;
+ };
+ };
+#else
+ union {
+ struct {
+ DWORD NameOffset:31;
+ DWORD NameIsString:1;
+ };
+ DWORD Name;
+ WORD Id;
+ };
+ union {
+ DWORD OffsetToData;
+ struct {
+ DWORD OffsetToDirectory:31;
+ DWORD DataIsDirectory:1;
+ };
+ };
+#endif
+} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;
+
+typedef struct _IMAGE_RESOURCE_DIRECTORY {
+ DWORD Characteristics;
+ DWORD TimeDateStamp;
+ WORD MajorVersion;
+ WORD MinorVersion;
+ WORD NumberOfNamedEntries;
+ WORD NumberOfIdEntries;
+ IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
+} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;
+
+typedef struct _IMAGE_RESOURCE_DATA_ENTRY {
+ DWORD OffsetToData;
+ DWORD Size;
+ DWORD CodePage;
+ DWORD Reserved;
+} IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY;
+
+typedef struct tagVS_FIXEDFILEINFO {
+ DWORD dwSignature; /* e.g. 0xfeef04bd */
+ DWORD dwStrucVersion; /* e.g. 0x00000042 = "0.42" */
+ DWORD dwFileVersionMS; /* e.g. 0x00030075 = "3.75" */
+ DWORD dwFileVersionLS; /* e.g. 0x00000031 = "0.31" */
+ DWORD dwProductVersionMS; /* e.g. 0x00030010 = "3.10" */
+ DWORD dwProductVersionLS; /* e.g. 0x00000031 = "0.31" */
+ DWORD dwFileFlagsMask; /* = 0x3F for version "0.42" */
+ DWORD dwFileFlags; /* e.g. VFF_DEBUG | VFF_PRERELEASE */
+ DWORD dwFileOS; /* e.g. VOS_DOS_WINDOWS16 */
+ DWORD dwFileType; /* e.g. VFT_DRIVER */
+ DWORD dwFileSubtype; /* e.g. VFT2_DRV_KEYBOARD */
+ DWORD dwFileDateMS; /* e.g. 0 */
+ DWORD dwFileDateLS; /* e.g. 0 */
+} VS_FIXEDFILEINFO;
+
+typedef struct _VS_VERSIONINFO {
+ WORD wLength;
+ WORD wValueLength;
+ WORD wType;
+ WORD szKey[16];
+ WORD Padding1[1];
+ VS_FIXEDFILEINFO Value;
+} VS_VERSIONINFO, *PVS_VERSIONINFO;
+
+#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code
+#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable
+
+#ifdef WORDS_BIGENDIAN
+#define LTOBS(x) ltobs(x)
+#define LTOBL(x) ltobl(x)
+WORD ltobs(WORD x);
+DWORD ltobl(DWORD x);
+#else
+#define LTOBS(x) (x)
+#define LTOBL(x) (x)
+#endif
+
+int check_init(const char *dataFile);
+void V2_check(const BYTE *seed, char *final_str);
+void check_free();
+DWORD getVer(const char *file);
+int cocoaPath();
+
+#endif
diff --git a/CocoaMento-Src/mentohust-src/myconfig.c b/CocoaMento-Src/mentohust-src/myconfig.c
new file mode 100644
index 0000000..f0e2194
--- /dev/null
+++ b/CocoaMento-Src/mentohust-src/myconfig.c
@@ -0,0 +1,597 @@
+/* -*- Mode: C; tab-width: 4; -*- */
+/*
+* Copyright (C) 2009, HustMoon Studio
+*
+* 文件名称:myconfig.c
+* 摘 要:初始化认证参数
+* 作 者:HustMoon@BYHH
+* 邮 箱:www.ehust@gmail.com
+*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#else
+static const char *VERSION = "0.3.1";
+static const char *PACKAGE_BUGREPORT = "http://code.google.com/p/mentohust/issues/list";
+#endif
+
+#include "myconfig.h"
+#include "myini.h"
+#include "myfunc.h"
+#include "dlfunc.h"
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define ACCOUNT_SIZE 65 /* 用户名密码长度*/
+#define NIC_SIZE 16 /* 网卡名最大长度 */
+#define MAX_PATH 255 /* FILENAME_MAX */
+#define D_TIMEOUT 8 /* 默认超时间隔 */
+#define D_ECHOINTERVAL 30 /* 默认心跳间隔 */
+#define D_RESTARTWAIT 15 /* 默认重连间隔 */
+#define D_STARTMODE 0 /* 默认组播模式 */
+#define D_DHCPMODE 0 /* 默认DHCP模式 */
+#define D_DAEMONMODE 0 /* 默认daemon模式 */
+#define D_MAXFAIL 0 /* 默认允许失败次数 */
+
+static const char *D_DHCPSCRIPT = "dhclient"; /* 默认DHCP脚本 */
+static const char *CFG_FILE ="mentohust.conf"; /* 配置文件 */
+static char *LOG_FILE = "mentohust.log"; /* 日志文件 */
+
+static const char *LOCK_FILE = "/var/run/mentohust.pid"; /* 锁文件 */
+#define LOCKMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) /* 创建掩码 */
+
+#ifndef NO_NOTIFY
+#define D_SHOWNOTIFY 5 /* 默认Show Notify模式 */
+int showNotify = D_SHOWNOTIFY; /* 显示通知 */
+#endif
+
+extern int bufType; /*0内置xrgsu 1内置Win 2仅文件 3文件+校验*/
+extern u_char version[]; /* 版本 */
+char userName[ACCOUNT_SIZE] = ""; /* 用户名 */
+char password[ACCOUNT_SIZE] = ""; /* 密码 */
+char nic[NIC_SIZE] = ""; /* 网卡名 */
+char dataFile[MAX_PATH] = ""; /* 数据文件 */
+char dhcpScript[MAX_PATH] = ""; /* DHCP脚本 */
+u_int32_t ip = 0; /* 本机IP */
+u_int32_t mask = 0; /* 子网掩码 */
+u_int32_t gateway = 0; /* 网关 */
+u_int32_t dns = 0; /* DNS */
+u_int32_t pingHost = 0; /* ping */
+u_char localMAC[6]; /* 本机MAC */
+u_char destMAC[6]; /* 服务器MAC */
+unsigned timeout = D_TIMEOUT; /* 超时间隔 */
+unsigned echoInterval = D_ECHOINTERVAL; /* 心跳间隔 */
+unsigned restartWait = D_RESTARTWAIT; /* 失败等待 */
+unsigned startMode = D_STARTMODE; /* 组播模式 */
+unsigned dhcpMode = D_DHCPMODE; /* DHCP模式 */
+unsigned maxFail = D_MAXFAIL; /* 允许失败次数 */
+pcap_t *hPcap = NULL; /* Pcap句柄 */
+int lockfd = -1; /* 锁文件描述符 */
+
+static int readFile(int *daemonMode); /* 读取配置文件来初始化 */
+static void readArg(char argc, char **argv, int *saveFlag, int *exitFlag, int *daemonMode); /* 读取命令行参数来初始化 */
+static void showHelp(const char *fileName); /* 显示帮助信息 */
+static int getAdapter(); /* 查找网卡名 */
+static void printConfig(); /* 显示初始化后的认证参数 */
+static int openPcap(); /* 初始化pcap、设置过滤器 */
+static void saveConfig(int daemonMode); /* 保存参数 */
+static void checkRunning(int exitFlag, int daemonMode); /* 检测是否已运行 */
+
+
+#ifndef NO_ENCODE_PASS
+static const unsigned char base64Tab[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"};
+static const char xorRuijie[] = {"~!:?$*<(qw2e5o7i8x12c6m67s98w43d2l45we82q3iuu1z4xle23rt4oxclle34e54u6r8m"};
+
+static int encodePass(char *dst, const char *osrc) {
+ unsigned char in[3], buf[70];
+ unsigned char *src = buf;
+ int sz = strlen(osrc);
+ int i, len;
+ if (sizeof(xorRuijie) < sz)
+ return -1;
+ for(i=0; i 0) {
+ for (len=0, i=0; i<3; i++, sz--) {
+ if (sz > 0) {
+ len++;
+ in[i] = src[i];
+ } else in[i] = 0;
+ }
+ src += 3;
+ if (len) {
+ dst[0] = base64Tab[ in[0] >> 2 ];
+ dst[1] = base64Tab[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
+ dst[2] = len > 1 ? base64Tab[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '=';
+ dst[3] = len > 2 ? base64Tab[ in[2] & 0x3f ] : '=';
+ dst += 4;
+ }
+ }
+ *dst = '\0';
+ return 0;
+}
+
+static int decodePass(char *dst, const char *src) {
+ unsigned esi = 0, idx = 0;
+ int i=0, j=0, equal=0;
+ for(; src[i]!='\0'; i++) {
+ if (src[i] == '=') {
+ if (++equal > 2)
+ return -1;
+ } else {
+ for(idx=0; base64Tab[idx]!='\0'; idx++) {
+ if(base64Tab[idx] == src[i])
+ break;
+ }
+ if (idx == 64)
+ return -1;
+ esi += idx;
+ }
+ if(i%4 == 3) {
+ dst[j++] = (char)(esi>>16);
+ if(equal < 2)
+ dst[j++] = (char)(esi>>8);
+ if(equal < 1)
+ dst[j++] = (char)esi;
+ esi = 0;
+ equal = 0;
+ }
+ esi <<= 6;
+ }
+ if (i%4!=0 || sizeof(xorRuijie)= 3) {
+ unsigned ver[2];
+ if (sscanf(tmp, "%u.%u", ver, ver+1)!=EOF && ver[0]!=0) {
+ version[0] = ver[0];
+ version[1] = ver[1];
+ bufType = 1;
+ }
+ }
+ getString(buf, "MentoHUST", "IP", "255.255.255.255", tmp, sizeof(tmp));
+ ip = inet_addr(tmp);
+ getString(buf, "MentoHUST", "Mask", "255.255.255.255", tmp, sizeof(tmp));
+ mask = inet_addr(tmp);
+ getString(buf, "MentoHUST", "Gateway", "0.0.0.0", tmp, sizeof(tmp));
+ gateway = inet_addr(tmp);
+ getString(buf, "MentoHUST", "DNS", "0.0.0.0", tmp, sizeof(tmp));
+ dns = inet_addr(tmp);
+ getString(buf, "MentoHUST", "PingHost", "0.0.0.0", tmp, sizeof(tmp));
+ pingHost = inet_addr(tmp);
+ timeout = getInt(buf, "MentoHUST", "Timeout", D_TIMEOUT) % 100;
+ echoInterval = getInt(buf, "MentoHUST", "EchoInterval", D_ECHOINTERVAL) % 1000;
+ restartWait = getInt(buf, "MentoHUST", "RestartWait", D_RESTARTWAIT) % 100;
+ startMode = getInt(buf, "MentoHUST", "StartMode", D_STARTMODE) % 3;
+ dhcpMode = getInt(buf, "MentoHUST", "DhcpMode", D_DHCPMODE) % 4;
+#ifndef NO_NOTIFY
+ showNotify = getInt(buf, "MentoHUST", "ShowNotify", D_SHOWNOTIFY) % 21;
+#endif
+ *daemonMode = getInt(buf, "MentoHUST", "DaemonMode", D_DAEMONMODE) % 4;
+ maxFail = getInt(buf, "MentoHUST", "MaxFail", D_MAXFAIL);
+ free(buf);
+ return 0;
+}
+
+static void readArg(char argc, char **argv, int *saveFlag, int *exitFlag, int *daemonMode)
+{
+ char *str, c;
+ int i;
+ for (i=1; i 2)
+ *exitFlag = 2;
+ else {
+ *exitFlag = 1;
+ return;
+ }
+ } else if (strlen(str) > 2) {
+ if (c == 'u')
+ strncpy(userName, str+2, sizeof(userName)-1);
+ else if (c == 'p')
+ strncpy(password, str+2, sizeof(password)-1);
+ else if (c == 'n')
+ strncpy(nic, str+2, sizeof(nic)-1);
+ else if (c == 'f')
+ strncpy(dataFile, str+2, sizeof(dataFile)-1);
+ else if (c == 'c')
+ strncpy(dhcpScript, str+2, sizeof(dhcpScript)-1);
+ else if (c=='v' && strlen(str+2)>=3) {
+ unsigned ver[2];
+ if (sscanf(str+2, "%u.%u", ver, ver+1) != EOF) {
+ if (ver[0] == 0)
+ bufType = 0;
+ else {
+ version[0] = ver[0];
+ version[1] = ver[1];
+ bufType = 1;
+ }
+ }
+ }
+ else if (c == 'i')
+ ip = inet_addr(str+2);
+ else if (c == 'm')
+ mask = inet_addr(str+2);
+ else if (c == 'g')
+ gateway = inet_addr(str+2);
+ else if (c == 's')
+ dns = inet_addr(str+2);
+ else if (c == 'o')
+ pingHost = inet_addr(str+2);
+ else if (c == 't')
+ timeout = atoi(str+2) % 100;
+ else if (c == 'e')
+ echoInterval = atoi(str+2) % 1000;
+ else if (c == 'r')
+ restartWait = atoi(str+2) % 100;
+ else if (c == 'a')
+ startMode = atoi(str+2) % 3;
+ else if (c == 'd')
+ dhcpMode = atoi(str+2) % 4;
+#ifndef NO_NOTIFY
+ else if (c == 'y')
+ showNotify = atoi(str+2) % 21;
+#endif
+ else if (c == 'b')
+ *daemonMode = atoi(str+2) % 4;
+ else if (c == 'l')
+ maxFail = atoi(str+2);
+ }
+ }
+}
+
+static void showHelp(const char *fileName)
+{
+ char *helpString =
+ "用法:\t%s [-选项][参数]\n"
+ "选项:\t-h 显示本帮助信息\n"
+ "\t-k -k(退出程序) 其他(重启程序)\n"
+ "\t-w 保存参数到配置文件\n"
+ "\t-u 用户名\n"
+ "\t-p 密码\n"
+ "\t-n 网卡名\n"
+ "\t-i IP[默认本机IP]\n"
+ "\t-m 子网掩码[默认本机掩码]\n"
+ "\t-g 网关[默认0.0.0.0]\n"
+ "\t-s DNS[默认0.0.0.0]\n"
+ "\t-o Ping主机[默认0.0.0.0,表示关闭该功能]\n"
+ "\t-t 认证超时(秒)[默认8]\n"
+ "\t-e 响应间隔(秒)[默认30]\n"
+ "\t-r 失败等待(秒)[默认15]\n"
+ "\t-l 允许失败次数[默认0,表示无限制]\n"
+ "\t-a 组播地址: 0(标准) 1(锐捷) 2(赛尔) [默认0]\n"
+ "\t-d DHCP方式: 0(不使用) 1(二次认证) 2(认证后) 3(认证前) [默认0]\n"
+ "\t-b 是否后台运行: 0(否) 1(是,关闭输出) 2(是,保留输出) 3(是,输出到文件) [默认0]\n"
+#ifndef NO_NOTIFY
+ "\t-y 是否显示通知: 0(否) 1~20(是) [默认5]\n"
+#endif
+ "\t-v 客户端版本号[默认0.00表示兼容xrgsu]\n"
+ "\t-f 自定义数据文件[默认不使用]\n"
+ "\t-c DHCP脚本[默认dhclient]\n"
+ "例如:\t%s -uusername -ppassword -neth0 -i192.168.0.1 -m255.255.255.0 -g0.0.0.0 -s0.0.0.0 -o0.0.0.0 -t8 -e30 -r15 -a0 -d1 -b0 -v4.10 -fdefault.mpf -cdhclient\n"
+ "注意:使用时请确保是以root权限运行!\n\n";
+ printf(helpString, fileName, fileName);
+ exit(EXIT_SUCCESS);
+}
+
+static int getAdapter()
+{
+ pcap_if_t *alldevs, *d;
+ int num = 0, avail = 0, i;
+ char errbuf[PCAP_ERRBUF_SIZE];
+ if (pcap_findalldevs(&alldevs, errbuf)==-1 || alldevs==NULL)
+ {
+ printf("!! 查找网卡失败: %s\n", errbuf);
+ return -1;
+ }
+ for (d=alldevs; d!=NULL; d=d->next)
+ {
+ num++;
+ if (!(d->flags & PCAP_IF_LOOPBACK) && strcmp(d->name, "any")!=0)
+ {
+ printf("** 网卡[%d]:\t%s\n", num, d->name);
+ avail++;
+ i = num;
+ }
+ }
+ if (avail == 0)
+ {
+ pcap_freealldevs(alldevs);
+ printf("!! 找不到网卡!\n");
+ return -1;
+ }
+ if (avail > 1)
+ {
+ printf("!? 请选择网卡[1-%d]: ", num);
+ exit(EXIT_SUCCESS);
+ }
+ for (d=alldevs; i>1; d=d->next, i--);
+ strncpy(nic, d->name, sizeof(nic)-1);
+ pcap_freealldevs(alldevs);
+ return 0;
+}
+
+static void printConfig()
+{
+ char *addr[] = {"标准", "锐捷", "赛尔"};
+ char *dhcp[] = {"不使用", "二次认证", "认证后", "认证前"};
+ printf("** 用户名:\t%s\n", userName);
+ /* printf("** 密码:\t%s\n", password); */
+ printf("** 网卡: \t%s\n", nic);
+ if (gateway)
+ printf("** 网关地址:\t%s\n", formatIP(gateway));
+ if (dns)
+ printf("** DNS地址:\t%s\n", formatIP(dns));
+ if (pingHost)
+ printf("** 智能重连:\t%s\n", formatIP(pingHost));
+ printf("** 认证超时:\t%u秒\n", timeout);
+ printf("** 响应间隔:\t%u秒\n", echoInterval);
+ printf("** 失败等待:\t%u秒\n", restartWait);
+ printf("** 允许失败:\t%u次\n", maxFail);
+ printf("** 组播地址:\t%s\n", addr[startMode]);
+ printf("** DHCP方式:\t%s\n", dhcp[dhcpMode]);
+#ifndef NO_NOTIFY
+ if (showNotify)
+ printf("** 通知超时:\t%d秒\n", showNotify);
+#endif
+ if (bufType >= 2)
+ printf("** 数据文件:\t%s\n", dataFile);
+ if (dhcpMode != 0)
+ printf("** DHCP脚本:\t%s\n", dhcpScript);
+}
+
+static int openPcap()
+{
+ char buf[PCAP_ERRBUF_SIZE], *fmt;
+ struct bpf_program fcode;
+ if ((hPcap = pcap_open_live(nic, 2048, 1, 1000, buf)) == NULL)
+ {
+ printf("!! 打开网卡%s失败: %s\n", nic, buf);
+ return -1;
+ }
+ fmt = formatHex(localMAC, 6);
+#ifndef NO_ARP
+ sprintf(buf, "((ether proto 0x888e and (ether dst %s or ether dst 01:80:c2:00:00:03)) "
+ "or ether proto 0x0806) and not ether src %s", fmt, fmt);
+#else
+ sprintf(buf, "ether proto 0x888e and (ether dst %s or ether dst 01:80:c2:00:00:03) "
+ "and not ether src %s", fmt, fmt);
+#endif
+ if (pcap_compile(hPcap, &fcode, buf, 0, 0xffffffff) == -1
+ || pcap_setfilter(hPcap, &fcode) == -1)
+ {
+ printf("!! 设置pcap过滤器失败: %s\n", pcap_geterr(hPcap));
+ return -1;
+ }
+ pcap_freecode(&fcode);
+ return 0;
+}
+
+static void saveConfig(int daemonMode)
+{
+ char *buf = loadFile(CFG_FILE);
+ if (buf == NULL) {
+ buf = (char *)malloc(1);
+ buf[0] = '\0';
+ }
+ setString(&buf, "MentoHUST", "DhcpScript", dhcpScript);
+ setString(&buf, "MentoHUST", "DataFile", dataFile);
+ if (bufType != 0) {
+ char ver[10];
+ sprintf(ver, "%u.%u", version[0], version[1]);
+ setString(&buf, "MentoHUST", "Version", ver);
+ } else
+ setString(&buf, "MentoHUST", "Version", "0.00");
+#ifndef NO_NOTIFY
+ setInt(&buf, "MentoHUST", "ShowNotify", showNotify);
+#endif
+ setInt(&buf, "MentoHUST", "DaemonMode", daemonMode);
+ setInt(&buf, "MentoHUST", "DhcpMode", dhcpMode);
+ setInt(&buf, "MentoHUST", "StartMode", startMode);
+ setInt(&buf, "MentoHUST", "MaxFail", maxFail);
+ setInt(&buf, "MentoHUST", "RestartWait", restartWait);
+ setInt(&buf, "MentoHUST", "EchoInterval", echoInterval);
+ setInt(&buf, "MentoHUST", "Timeout", timeout);
+ setString(&buf, "MentoHUST", "PingHost", formatIP(pingHost));
+ setString(&buf, "MentoHUST", "DNS", formatIP(dns));
+ setString(&buf, "MentoHUST", "Gateway", formatIP(gateway));
+ setString(&buf, "MentoHUST", "Mask", formatIP(mask));
+ setString(&buf, "MentoHUST", "IP", formatIP(ip));
+ setString(&buf, "MentoHUST", "Nic", nic);
+#ifdef NO_ENCODE_PASS
+ setString(&buf, "MentoHUST", "Password", password);
+#else
+ char pass[ACCOUNT_SIZE*4/3];
+ encodePass(pass, password);
+ setString(&buf, "MentoHUST", "EncodePass", pass);
+#endif
+ setString(&buf, "MentoHUST", "Username", userName);
+ if (saveFile(buf, CFG_FILE) != 0)
+ printf("!! 保存认证参数到%s失败!\n", CFG_FILE);
+ else
+ printf("** 认证参数已成功保存到%s.\n", CFG_FILE);
+ free(buf);
+}
+
+static void checkRunning(int exitFlag, int daemonMode)
+{
+ struct flock fl;
+ lockfd = open (LOCK_FILE, O_RDWR|O_CREAT, LOCKMODE);
+ if (lockfd < 0) {
+ perror("~! 打开锁文件失败"); /* perror真的很好啊,以前没用它真是太亏了 */
+ printf("~! 打开锁文件失败\n");
+ goto error_exit;
+ }
+ fl.l_start = 0;
+ fl.l_whence = SEEK_SET;
+ fl.l_len = 0;
+ fl.l_type = F_WRLCK;
+ if (fcntl(lockfd, F_GETLK, &fl) < 0) {
+ perror("~! 获取文件锁失败");
+ printf("~! 获取文件锁失败\n");
+ goto error_exit;
+ }
+ if (exitFlag) {
+ if (fl.l_type != F_UNLCK) {
+ printf(">> 已发送退出信号给MentoHUST进程(PID=%d).\n", fl.l_pid);
+ if (kill(fl.l_pid, SIGINT) == -1)
+ perror("!! 结束进程失败");
+ }
+ else
+ printf("!! 没有MentoHUST正在运行!\n");
+ if (exitFlag == 1)
+ exit(EXIT_SUCCESS);
+ }
+ else if (fl.l_type != F_UNLCK) {
+ printf("!! MentoHUST已经运行(PID=%d)!\n", fl.l_pid);
+ exit(EXIT_FAILURE);
+ }
+// if (daemonMode) { /* 貌似我过早进入后台模式了,就给个选项保留输出或者输出到文件吧 */
+// printf(">> 进入后台运行模式,使用参数-k可退出认证。\n");
+// if (daemon(0, (daemonMode+1)%2))
+// perror("!! 后台运行失败");
+// else if (daemonMode == 3) {
+// freopen(LOG_FILE, "w", stdout);
+// freopen(LOG_FILE, "a", stderr);
+// }
+// }
+ fl.l_type = F_WRLCK;
+ fl.l_pid = getpid();
+ if (fcntl(lockfd, F_SETLKW, &fl) < 0) {
+ perror("~! 加锁失败");
+ goto error_exit;
+ }
+ return;
+
+error_exit:
+#ifndef NO_NOTIFY
+ if (showNotify)
+ show_notify("MentoHUST - 错误提示", "操作锁文件失败,请检查是否为root权限!");
+#endif
+ exit(EXIT_FAILURE);
+}
diff --git a/CocoaMento-Src/mentohust-src/myconfig.h b/CocoaMento-Src/mentohust-src/myconfig.h
new file mode 100644
index 0000000..9647c05
--- /dev/null
+++ b/CocoaMento-Src/mentohust-src/myconfig.h
@@ -0,0 +1,15 @@
+/*
+* Copyright (C) 2009, HustMoon Studio
+*
+* 文件名称:myconfig.h
+* 摘 要:初始化认证参数
+* 作 者:HustMoon@BYHH
+*/
+#ifndef HUSTMOON_MYCONFIG_H
+#define HUSTMOON_MYCONFIG_H
+
+#define NO_NOTIFY
+
+int initConfig(int argc, char **argv); /* 初始化配置 */
+
+#endif
diff --git a/CocoaMento-Src/mentohust-src/myfunc.c b/CocoaMento-Src/mentohust-src/myfunc.c
new file mode 100644
index 0000000..54af6e8
--- /dev/null
+++ b/CocoaMento-Src/mentohust-src/myfunc.c
@@ -0,0 +1,530 @@
+/* -*- Mode: C; tab-width: 4; -*- */
+/*
+* Copyright (C) 2009, HustMoon Studio
+*
+* 文件名称:myfunc.c
+* 摘 要:认证相关算法及方法
+* 作 者:HustMoon@BYHH
+*/
+#include "myfunc.h"
+#include "md5.h"
+#include "mycheck.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#ifndef SIOCGIFHWADDR /* BSD、MacOS */
+#include
+#include
+#endif
+#include
+
+const u_char STANDARD_ADDR[] = {0x01,0x80,0xC2,0x00,0x00,0x03};
+const u_char RUIJIE_ADDR[] = {0x01,0xD0,0xF8,0x00,0x00,0x03};
+static const char *DATAFILE = "../Resources/data/"; /* 默认数据文件(目录) */
+
+static int dataOffset; /* 抓包偏移 */
+static u_int32_t echoKey = 0, echoNo = 0; /* Echo阶段所需 */
+u_char *fillBuf = NULL; /* 填充包地址 */
+int fillSize = 0; /* 填充包大小 */
+int bufType = 0; /*0内置xrgsu 1内置Win 2仅文件 3文件+校验*/
+u_char version[2]; /* 版本 */
+#ifndef NO_ARP
+u_int32_t rip = 0; /* 实际IP */
+u_char gateMAC[6]; /* 网关MAC */
+#endif
+
+extern char password[];
+extern char nic[];
+extern char dataFile[];
+extern u_int32_t ip, mask, gateway, dns, pingHost;
+extern u_char localMAC[], destMAC[];
+extern unsigned startMode, dhcpMode;
+
+static int checkFile(); /* 检查数据文件 */
+static int getVersion(); /* 获取8021x.exe版本号 */
+static int getAddress(); /* 获取网络地址 */
+static u_char encode(u_char base); /* 锐捷算法,颠倒一个字节的8位 */
+static void checkSum(u_char *buf); /* 锐捷算法,计算两个字节的检验值 */
+static int setProperty(u_char type, const u_char *value, int length); /* 设置指定属性 */
+static int readPacket(int type); /* 读取数据 */
+static int Check(const u_char *md5Seed); /* 校验算法 */
+
+char *formatIP(u_int32_t ip)
+{
+ static char tmp[16];
+ u_char *p = (u_char *)(&ip);
+ sprintf(tmp, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+ return tmp;
+}
+
+char *formatHex(const void *buf, int length)
+{
+ static char hex[385];
+ u_char *p = (u_char *)buf;
+ int i;
+ if (length > 128)
+ length = 128;
+ for (i=0; i0x397)
+ goto fileError;
+ return 0;
+
+fileError:
+ if (dataFile[strlen(dataFile)-1] != '/')
+ printf("!! 所选文件%s无效,改用内置数据认证。\n", dataFile);
+ fflush(stdout);
+ return -1;
+}
+
+static int getVersion() {
+ char file[0x100], *p;
+ DWORD ver;
+ strcpy(file, dataFile);
+ if ((p=strrchr(file, '/')+1) == (void *)1)
+ p = file;
+ strcpy(p, "8021x.exe");
+ if ((ver=getVer(file)) == (DWORD)-1)
+ return -1;
+ p = (char *)&ver;
+ version[0] = p[2];
+ version[1] = p[0];
+ bufType = 1;
+ return 0;
+}
+
+void newBuffer()
+{
+ if (dataFile[0] == '\0')
+ strcpy(dataFile, DATAFILE);
+ getVersion();
+ if (checkFile() == 0)
+ bufType += 2;
+ else fillSize = (bufType==0 ? 0x80 : 0x1d7);
+ fillBuf = (u_char *)malloc(fillSize);
+}
+
+static int getAddress()
+{
+ struct ifreq ifr;
+#ifndef SIOCGIFHWADDR /* BSD、MacOS */
+ struct ifaddrs *ifap, *p = NULL;
+ struct sockaddr_dl *sdl;
+#endif
+ int sock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sock < 0)
+ {
+ printf("!! 创建套接字失败!\n");
+ fflush(stdout);
+ return -1;
+ }
+ strcpy(ifr.ifr_name, nic);
+
+#ifdef SIOCGIFHWADDR
+ if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0)
+ goto getMACError;
+ memcpy(localMAC, ifr.ifr_hwaddr.sa_data, 6);
+#else
+ if (getifaddrs(&ifap) == 0)
+ {
+ for (p=ifap; p; p=p->ifa_next)
+ {
+ if (p->ifa_name && strcmp(p->ifa_name, nic)==0)
+ {
+ sdl = (struct sockaddr_dl *)p->ifa_addr;
+ memcpy(localMAC, sdl->sdl_data + sdl->sdl_nlen, 6);
+ break;
+ }
+ }
+ freeifaddrs(ifap);
+ }
+ if (p == NULL)
+ goto getMACError;
+#endif
+
+ if (startMode == 0)
+ memcpy(destMAC, STANDARD_ADDR, 6);
+ else if (startMode == 1)
+ memcpy(destMAC, RUIJIE_ADDR, 6);
+
+#ifndef NO_ARP
+ gateMAC[0] = 0xFE;
+ if (ioctl(sock, SIOCGIFADDR, &ifr) < 0)
+ printf("!! 在网卡%s上获取IP失败!\n", nic);
+ else {
+ rip = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
+ if (gateway!=0 && (startMode%3!=2 || ((u_char *)&gateway)[3]!=0x02))
+ gateMAC[0] = 0xFF;
+ }
+ if (dhcpMode!=0 || ip==-1)
+ ip = rip;
+#else
+ if (dhcpMode!=0 || ip==-1) {
+ if (ioctl(sock, SIOCGIFADDR, &ifr) < 0)
+ printf("!! 在网卡%s上获取IP失败!\n", nic);
+ else
+ ip = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
+ }
+#endif
+
+ if (dhcpMode!=0 || mask==-1) {
+ if (ioctl(sock, SIOCGIFNETMASK, &ifr) < 0)
+ printf("!! 在网卡%s上获取子网掩码失败!\n", nic);
+ else
+ mask = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
+ }
+ fflush(stdout);
+ close(sock);
+
+ printf("** 本机MAC:\t%s\n", formatHex(localMAC, 6));
+ printf("** 使用IP:\t%s\n", formatIP(ip));
+ fflush(stdout);
+ printf("** 子网掩码:\t%s\n", formatIP(mask));
+ return 0;
+
+getMACError:
+ close(sock);
+ printf("!! 在网卡%s上获取MAC失败!\n", nic);
+ fflush(stdout);
+ return -1;
+}
+
+static u_char encode(u_char base) /* 算法,将一个字节的8位颠倒并取反 */
+{
+ u_char result = 0;
+ int i;
+ for (i=0; i<8; i++)
+ {
+ result <<= 1;
+ result |= base&0x01;
+ base >>= 1;
+ }
+ return ~result;
+}
+
+static void checkSum(u_char *buf) /* 算法,计算两个字节的checksum */
+{
+ u_char table[] =
+ {
+ 0x00,0x00,0x21,0x10,0x42,0x20,0x63,0x30,0x84,0x40,0xA5,0x50,0xC6,0x60,0xE7,0x70,
+ 0x08,0x81,0x29,0x91,0x4A,0xA1,0x6B,0xB1,0x8C,0xC1,0xAD,0xD1,0xCE,0xE1,0xEF,0xF1,
+ 0x31,0x12,0x10,0x02,0x73,0x32,0x52,0x22,0xB5,0x52,0x94,0x42,0xF7,0x72,0xD6,0x62,
+ 0x39,0x93,0x18,0x83,0x7B,0xB3,0x5A,0xA3,0xBD,0xD3,0x9C,0xC3,0xFF,0xF3,0xDE,0xE3,
+ 0x62,0x24,0x43,0x34,0x20,0x04,0x01,0x14,0xE6,0x64,0xC7,0x74,0xA4,0x44,0x85,0x54,
+ 0x6A,0xA5,0x4B,0xB5,0x28,0x85,0x09,0x95,0xEE,0xE5,0xCF,0xF5,0xAC,0xC5,0x8D,0xD5,
+ 0x53,0x36,0x72,0x26,0x11,0x16,0x30,0x06,0xD7,0x76,0xF6,0x66,0x95,0x56,0xB4,0x46,
+ 0x5B,0xB7,0x7A,0xA7,0x19,0x97,0x38,0x87,0xDF,0xF7,0xFE,0xE7,0x9D,0xD7,0xBC,0xC7,
+ 0xC4,0x48,0xE5,0x58,0x86,0x68,0xA7,0x78,0x40,0x08,0x61,0x18,0x02,0x28,0x23,0x38,
+ 0xCC,0xC9,0xED,0xD9,0x8E,0xE9,0xAF,0xF9,0x48,0x89,0x69,0x99,0x0A,0xA9,0x2B,0xB9,
+ 0xF5,0x5A,0xD4,0x4A,0xB7,0x7A,0x96,0x6A,0x71,0x1A,0x50,0x0A,0x33,0x3A,0x12,0x2A,
+ 0xFD,0xDB,0xDC,0xCB,0xBF,0xFB,0x9E,0xEB,0x79,0x9B,0x58,0x8B,0x3B,0xBB,0x1A,0xAB,
+ 0xA6,0x6C,0x87,0x7C,0xE4,0x4C,0xC5,0x5C,0x22,0x2C,0x03,0x3C,0x60,0x0C,0x41,0x1C,
+ 0xAE,0xED,0x8F,0xFD,0xEC,0xCD,0xCD,0xDD,0x2A,0xAD,0x0B,0xBD,0x68,0x8D,0x49,0x9D,
+ 0x97,0x7E,0xB6,0x6E,0xD5,0x5E,0xF4,0x4E,0x13,0x3E,0x32,0x2E,0x51,0x1E,0x70,0x0E,
+ 0x9F,0xFF,0xBE,0xEF,0xDD,0xDF,0xFC,0xCF,0x1B,0xBF,0x3A,0xAF,0x59,0x9F,0x78,0x8F,
+ 0x88,0x91,0xA9,0x81,0xCA,0xB1,0xEB,0xA1,0x0C,0xD1,0x2D,0xC1,0x4E,0xF1,0x6F,0xE1,
+ 0x80,0x10,0xA1,0x00,0xC2,0x30,0xE3,0x20,0x04,0x50,0x25,0x40,0x46,0x70,0x67,0x60,
+ 0xB9,0x83,0x98,0x93,0xFB,0xA3,0xDA,0xB3,0x3D,0xC3,0x1C,0xD3,0x7F,0xE3,0x5E,0xF3,
+ 0xB1,0x02,0x90,0x12,0xF3,0x22,0xD2,0x32,0x35,0x42,0x14,0x52,0x77,0x62,0x56,0x72,
+ 0xEA,0xB5,0xCB,0xA5,0xA8,0x95,0x89,0x85,0x6E,0xF5,0x4F,0xE5,0x2C,0xD5,0x0D,0xC5,
+ 0xE2,0x34,0xC3,0x24,0xA0,0x14,0x81,0x04,0x66,0x74,0x47,0x64,0x24,0x54,0x05,0x44,
+ 0xDB,0xA7,0xFA,0xB7,0x99,0x87,0xB8,0x97,0x5F,0xE7,0x7E,0xF7,0x1D,0xC7,0x3C,0xD7,
+ 0xD3,0x26,0xF2,0x36,0x91,0x06,0xB0,0x16,0x57,0x66,0x76,0x76,0x15,0x46,0x34,0x56,
+ 0x4C,0xD9,0x6D,0xC9,0x0E,0xF9,0x2F,0xE9,0xC8,0x99,0xE9,0x89,0x8A,0xB9,0xAB,0xA9,
+ 0x44,0x58,0x65,0x48,0x06,0x78,0x27,0x68,0xC0,0x18,0xE1,0x08,0x82,0x38,0xA3,0x28,
+ 0x7D,0xCB,0x5C,0xDB,0x3F,0xEB,0x1E,0xFB,0xF9,0x8B,0xD8,0x9B,0xBB,0xAB,0x9A,0xBB,
+ 0x75,0x4A,0x54,0x5A,0x37,0x6A,0x16,0x7A,0xF1,0x0A,0xD0,0x1A,0xB3,0x2A,0x92,0x3A,
+ 0x2E,0xFD,0x0F,0xED,0x6C,0xDD,0x4D,0xCD,0xAA,0xBD,0x8B,0xAD,0xE8,0x9D,0xC9,0x8D,
+ 0x26,0x7C,0x07,0x6C,0x64,0x5C,0x45,0x4C,0xA2,0x3C,0x83,0x2C,0xE0,0x1C,0xC1,0x0C,
+ 0x1F,0xEF,0x3E,0xFF,0x5D,0xCF,0x7C,0xDF,0x9B,0xAF,0xBA,0xBF,0xD9,0x8F,0xF8,0x9F,
+ 0x17,0x6E,0x36,0x7E,0x55,0x4E,0x74,0x5E,0x93,0x2E,0xB2,0x3E,0xD1,0x0E,0xF0,0x1E
+ };
+ u_char *checkSum = buf + 0x15;
+ int i, index;
+ for (i=0; i<0x15; i++)
+ {
+ index = checkSum[0] ^ buf[i];
+ checkSum[0] = checkSum[1] ^ table[index*2+1];
+ checkSum[1] = table[index*2];
+ }
+ for (i=0; i<0x17; i++)
+ buf[i] = encode(buf[i]);
+}
+
+int fillHeader()
+{
+ if (getAddress() == -1)
+ return -1;
+ memset(fillBuf, 0, fillSize);
+ fillBuf[0x02] = 0x13;
+ fillBuf[0x03] = 0x11;
+ if (dhcpMode != 0)
+ fillBuf[0x04] = 0x01; /* DHCP位,使用1、不使用0 */
+ memcpy(fillBuf+0x05, &ip, 4);
+ memcpy(fillBuf+0x09, &mask, 4);
+ memcpy(fillBuf+0x0D, &gateway, 4);
+ memcpy(fillBuf+0x11, &dns, 4);
+ checkSum(fillBuf);
+ return 0;
+}
+
+static int setProperty(u_char type, const u_char *value, int length)
+{
+ u_char *p = fillBuf+0x46, *end = fillBuf+fillSize-length-8; /* 形如1a 28 00 00 13 11 17 22,至少8个字节 */
+ while (p < end)
+ {
+ if (*p == 0x1a) /* 有些老版本没有前两个字节,包括xrgsu */
+ p += 2;
+ if (p[4] == type)
+ {
+ memcpy(p+4+p[5]-length, value, length);
+ return 0;
+ }
+ p += p[5] + 4;
+ }
+ return -1;
+}
+
+static int readPacket(int type)
+{
+ u_char dhcp[] = {0x00};
+ FILE *fp = fopen(dataFile, "rb");
+ if (fp == NULL)
+ goto fileError;
+ type %= 2; /* 偶数读Start包,奇数读Md5包 */
+ fseek(fp, dataOffset+(fillSize-0x17)*type, SEEK_SET);
+ if (fread(fillBuf+0x17, fillSize-0x17, 1, fp) < 1) /* 前0x17字节是地址及校验值 */
+ {
+ fclose(fp);
+ goto fileError;
+ }
+ fclose(fp);
+ if (dhcpMode == 1) /* 二次认证第一次 */
+ dhcp[0] = 0x01;
+ setProperty(0x18, dhcp, 1);
+ setProperty(0x2D, localMAC, 6);
+ if (bufType == 3)
+ memcpy(fillBuf+0x3b, version, 2);
+ return 0;
+
+fileError:
+ printf("!! 所选文件%s无效,改用内置数据认证。\n", dataFile);
+ fflush(stdout);
+ bufType -= 2;
+ if (bufType==1 && fillSize<0x1d7) {
+ free(fillBuf);
+ fillSize = 0x1d7;
+ fillBuf = (u_char *)malloc(fillSize);
+ }
+ return -1;
+}
+
+void fillStartPacket()
+{
+ if (bufType <= 1) { /* 使用xrgsu? */
+ const u_char packet0[] = {
+ 0x00,0x00,0x13,0x11,0x38,0x30,0x32,0x31,0x78,0x2e,0x65,0x78,0x65,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x13,0x11,0x00,0x28,0x1a,
+ 0x28,0x00,0x00,0x13,0x11,0x17,0x22,0x91,0x66,0x64,0x93,0x67,0x60,0x65,0x62,0x62,
+ 0x94,0x61,0x69,0x67,0x63,0x91,0x93,0x92,0x68,0x66,0x93,0x91,0x66,0x95,0x65,0xaa,
+ 0xdc,0x64,0x98,0x96,0x6a,0x9d,0x66,0x00,0x00,0x13,0x11,0x18,0x06,0x02,0x00,0x00
+ };
+ const u_char packet1[] = {
+ 0x00,0x00,0x13,0x11,0x38,0x30,0x32,0x31,0x78,0x2e,0x65,0x78,0x65,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x04,0x0a,0x00,0x02,0x00,0x00,0x00,0x13,0x11,0x01,0x8c,0x1a,
+ 0x28,0x00,0x00,0x13,0x11,0x17,0x22,0x36,0x38,0x44,0x43,0x31,0x32,0x33,0x42,0x37,
+ 0x45,0x42,0x32,0x33,0x39,0x46,0x32,0x33,0x41,0x38,0x43,0x30,0x30,0x30,0x33,0x38,
+ 0x38,0x34,0x39,0x38,0x36,0x33,0x39,0x1a,0x0c,0x00,0x00,0x13,0x11,0x18,0x06,0x00,
+ 0x00,0x00,0x00,0x1a,0x0e,0x00,0x00,0x13,0x11,0x2d,0x08,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x1a,0x08,0x00,0x00,0x13,0x11,0x2f,0x02,0x1a,0x09,0x00,0x00,0x13,0x11,0x35,
+ 0x03,0x01,0x1a,0x18,0x00,0x00,0x13,0x11,0x36,0x12,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0x18,0x00,0x00,0x13,0x11,
+ 0x38,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x86,
+ 0x13,0x4c,0x1a,0x88,0x00,0x00,0x13,0x11,0x4d,0x82,0x36,0x38,0x64,0x63,0x31,0x32,
+ 0x33,0x62,0x30,0x37,0x65,0x62,0x32,0x33,0x39,0x66,0x32,0x33,0x61,0x38,0x30,0x64,
+ 0x63,0x66,0x32,0x35,0x38,0x37,0x35,0x64,0x30,0x35,0x37,0x37,0x30,0x63,0x37,0x32,
+ 0x31,0x65,0x34,0x35,0x36,0x34,0x35,0x65,0x35,0x33,0x37,0x61,0x62,0x33,0x35,0x31,
+ 0x62,0x62,0x36,0x33,0x31,0x35,0x35,0x61,0x65,0x31,0x36,0x32,0x36,0x31,0x36,0x37,
+ 0x65,0x62,0x30,0x39,0x32,0x32,0x33,0x65,0x32,0x61,0x30,0x61,0x37,0x38,0x30,0x33,
+ 0x31,0x31,0x36,0x31,0x61,0x63,0x30,0x39,0x64,0x61,0x32,0x64,0x63,0x30,0x37,0x33,
+ 0x36,0x39,0x33,0x61,0x34,0x66,0x35,0x61,0x32,0x39,0x32,0x38,0x36,0x37,0x35,0x31,
+ 0x66,0x39,0x37,0x66,0x34,0x64,0x30,0x34,0x36,0x38,0x1a,0x28,0x00,0x00,0x13,0x11,
+ 0x39,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x1a,0x48,0x00,0x00,0x13,0x11,0x54,0x42,0x48,0x55,0x53,0x54,0x4d,0x4f,
+ 0x4f,0x4e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0x08,0x00,0x00,0x13,0x11,
+ 0x55,0x02,0x1a,0x09,0x00,0x00,0x13,0x11,0x62,0x03,0x00,0x00,0x00,0x00,0x00,0x00
+ };
+ u_char dhcp[] = {0x00};
+ if (dhcpMode == 1) /* 二次认证第一次 */
+ dhcp[0] = 0x01;
+ if (bufType == 1) {
+ memcpy(fillBuf+0x17, packet1, sizeof(packet1));
+ memcpy(fillBuf+0x3b, version, 2);
+ } else
+ memcpy(fillBuf+0x17, packet0, sizeof(packet0));
+ setProperty(0x18, dhcp, 1);
+ setProperty(0x2D, localMAC, 6);
+ }
+ else if (readPacket(0) == -1) /* 读取数据失败就用默认的填充 */
+ fillStartPacket();
+}
+
+void fillMd5Packet(const u_char *md5Seed)
+{
+ if (bufType <= 1) { /* 不使用数据包? */
+ /* xrgsu的Md5包与Start包只有一个字节的差异,若以其他版本为基础,可进一步区别对待 */
+ fillStartPacket();
+ if (bufType == 1)
+ Check(md5Seed);
+ } else {
+ if (readPacket(1) == -1)
+ fillMd5Packet(md5Seed);
+ else
+ Check(md5Seed);
+ }
+ echoNo = 0x0000102B; /* 初始化echoNo */
+}
+
+static int Check(const u_char *md5Seed) /* 客户端校验 */
+{
+ char final_str[129];
+ int value;
+ printf("** 客户端版本:\t%d.%d\n", fillBuf[0x3B], fillBuf[0x3C]);
+ printf("** MD5种子:\t%s\n", formatHex(md5Seed, 16));
+ value = check_init(dataFile);
+ if (value == -1) {
+ printf("!! 缺少8021x.exe信息,客户端校验无法继续!\n");
+ fflush(stdout);
+ return 1;
+ }
+ V2_check(md5Seed, final_str);
+ printf("** V2校验值:\t%s\n", final_str);
+ setProperty(0x17, (u_char *)final_str, 32);
+ check_free();
+ return 0;
+}
+
+void fillEchoPacket(u_char *echoBuf)
+{
+ int i;
+ u_int32_t dd1=htonl(echoKey + echoNo), dd2=htonl(echoNo);
+ u_char *bt1=(u_char *)&dd1, *bt2=(u_char *)&dd2;
+ echoNo++;
+ for (i=0; i<4; i++)
+ {
+ echoBuf[0x18+i] = encode(bt1[i]);
+ echoBuf[0x22+i] = encode(bt2[i]);
+ }
+}
+
+void getEchoKey(const u_char *capBuf)
+{
+ int i, offset = 0x1c+capBuf[0x1b]+0x69+24; /* 通过比较了大量抓包,通用的提取点就是这样的 */
+ u_char *base;
+ echoKey = ntohl(*(u_int32_t *)(capBuf+offset));
+ base = (u_char *)(&echoKey);
+ for (i=0; i<4; i++)
+ base[i] = encode(base[i]);
+}
+
+u_char *checkPass(u_char id, const u_char *md5Seed, int seedLen)
+{
+ u_char md5Src[80];
+ int md5Len = strlen(password);
+ md5Src[0] = id;
+ memcpy(md5Src+1, password, md5Len);
+ md5Len++;
+ if (startMode % 3 == 2) /* 赛尔? */
+ {
+ memcpy(md5Src+md5Len, "xxghlmxhzb", 10);
+ md5Len += 10;
+ }
+ memcpy(md5Src+md5Len, md5Seed, seedLen);
+ md5Len += seedLen;
+ return ComputeHash(md5Src, md5Len);
+}
+
+void fillCernetAddr(u_char *buf)
+{
+ memcpy(buf+0x18, &ip, 4);
+ memcpy(buf+0x1C, &mask, 4);
+ memcpy(buf+0x20, &gateway, 4);
+ memset(buf+0x24, 0, 4); /* memcpy(buf+0x24, &dns, 4); */
+}
+
+int isOnline()
+{
+ u_char echoPacket[] =
+ {
+ 0x08,0x00,0x61,0xb2,0x02,0x00,0x01,0x00,0x57,0x65,0x6C,0x63,0x6F,0x6D,0x65,0x20,
+ 0x74,0x6F,0x20,0x4D,0x65,0x6E,0x74,0x6F,0x48,0x55,0x53,0x54,0x21,0x0A,0x43,0x6F,
+ 0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x39,
+ 0x20,0x48,0x75,0x73,0x74,0x4D,0x6F,0x6F,0x6E,0x20,0x53,0x74,0x75,0x64,0x69,0x6F
+ };
+ int sock=-1, rtVal, t;
+ struct pollfd pfd;
+ struct sockaddr_in dest;
+ if (pingHost == 0)
+ return 0;
+ memset(&dest, 0, sizeof(dest));
+ dest.sin_family = AF_INET;
+ dest.sin_addr.s_addr = pingHost;
+ if ((sock=socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
+ goto pingError;
+ pfd.fd = sock;
+ pfd.events = POLLIN;
+ for (t=1; t<=3; t++) {
+ if (sendto(sock, echoPacket, sizeof(echoPacket), 0,
+ (struct sockaddr *)&dest, sizeof(dest)) < 0)
+ goto pingError;
+ rtVal = poll(&pfd, 1, t*1000);
+ if (rtVal == -1)
+ goto pingError;
+ if (rtVal > 0) {
+ close(sock);
+ return 0;
+ }
+ }
+ close(sock);
+ return -1;
+
+pingError:
+ perror("!! Ping主机出错,关闭该功能");
+ fflush(stdout);
+ if (sock != -1)
+ close(sock);
+ pingHost = 0;
+ return 0;
+}
diff --git a/CocoaMento-Src/mentohust-src/myfunc.h b/CocoaMento-Src/mentohust-src/myfunc.h
new file mode 100644
index 0000000..9b7d68c
--- /dev/null
+++ b/CocoaMento-Src/mentohust-src/myfunc.h
@@ -0,0 +1,26 @@
+/*
+* Copyright (C) 2009, HustMoon Studio
+*
+* 文件名称:myfunc.h
+* 摘 要:认证相关算法及方法
+* 作 者:HustMoon@BYHH
+*/
+#ifndef HUSTMOON_MYFUNC_H
+#define HUSTMOON_MYFUNC_H
+
+#include
+
+char *formatIP(u_int32_t ip); /* 格式化IP */
+char *formatHex(const void *buf, int length); /* 格式化成十六进制形式 */
+void newBuffer(); /* 检测数据文件有效性并分配内存 */
+int fillHeader(); /* 填充网络地址及校验值部分 */
+void fillStartPacket(); /* 填充Start包 */
+void fillMd5Packet(const u_char *md5Seed); /* 填充Md5包 */
+void fillEchoPacket(u_char *buf); /* 填充Echo包 */
+void getEchoKey(const u_char *capBuf); /* 获取EchoKey */
+u_char *checkPass(u_char id, const u_char *md5Seed, int seedLen); /* 计算密码的md5 */
+void fillCernetAddr(u_char *buf); /* 填充赛尔网络地址 */
+int isOnline(); /* ping主机判断是否掉线 */
+
+#endif
+
diff --git a/CocoaMento-Src/mentohust-src/myini.c b/CocoaMento-Src/mentohust-src/myini.c
new file mode 100644
index 0000000..c4103ef
--- /dev/null
+++ b/CocoaMento-Src/mentohust-src/myini.c
@@ -0,0 +1,203 @@
+/* -*- Mode: C; tab-width: 4; -*- */
+/*
+* Copyright (C) 2009, HustMoon Studio
+*
+* 文件名称:myini.c
+* 摘 要:读取ini文件+写入ini文件
+* 作 者:HustMoon@BYHH
+* 修 改:2009.10.8
+*/
+#include "myini.h"
+#include
+#include
+
+#define NOT_COMMENT(c) (c!=';' && c!='#') /* 不是注释行 */
+
+#ifndef strnicmp
+#define strnicmp strncasecmp
+#endif
+
+static void getLine(const char *buf, int inStart, int *lineStart, int *lineEnd);
+static int findKey(const char *buf, const char *section, const char *key,
+ int *sectionStart, int *valueStart, unsigned long *valueSize);
+static int getSection(const char *buf, int inStart);
+
+char *loadFile(const char *fileName)
+{
+ FILE *fp = NULL;
+ long size = 0;
+ char *buf = NULL;
+ if ((fp=fopen(fileName, "rb")) == NULL)
+ return NULL;
+ fseek(fp, 0, SEEK_END);
+ size = ftell(fp);
+ rewind(fp);
+ buf = (char *)malloc(size+1);
+ buf[size] = '\0';
+ if (fread(buf, size, 1, fp) < 1)
+ {
+ free(buf);
+ buf = NULL;
+ }
+ fclose(fp);
+ return buf;
+}
+
+static void getLine(const char *buf, int inStart, int *lineStart, int *lineEnd)
+{
+ int start, end;
+ for (start=inStart; buf[start]==' ' || buf[start]=='\t' || buf[start]=='\r' || buf[start]=='\n'; start++);
+ for (end=start; buf[end]!='\r' && buf[end]!='\n' && buf[end]!='\0'; end++);
+ *lineStart = start;
+ *lineEnd = end;
+}
+
+static int findKey(const char *buf, const char *section, const char *key,
+ int *sectionStart, int *valueStart, unsigned long *valueSize)
+{
+ int lineStart, lineEnd, i;
+ for (*sectionStart=-1, lineEnd=0; buf[lineEnd]!='\0'; )
+ {
+ getLine(buf, lineEnd, &lineStart, &lineEnd);
+ if (buf[lineStart] == '[')
+ {
+ for (i=++lineStart; i /* for free() */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+char *loadFile(const char *fileName); /* 读取文件 */
+int getString(const char *buf, const char *section, const char *key,
+ const char *defaultValue, char *value, unsigned long size); /* 读取字符串 */
+int getInt(const char *buf, const char *section, const char *key, int defaultValue); /* 读取整数 */
+void setString(char **buf, const char *section, const char *key, const char *value); /* 设置字符串,value=NULL则删除key,key=NULL则删除section */
+void setInt(char **buf, const char *section, const char *key, int value); /* 设置整数 */
+int saveFile(const char *buf, const char *fileName); /* 写入文件 */
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/CocoaMento-Src/mentohust-src/mystate.c b/CocoaMento-Src/mentohust-src/mystate.c
new file mode 100644
index 0000000..c00c956
--- /dev/null
+++ b/CocoaMento-Src/mentohust-src/mystate.c
@@ -0,0 +1,357 @@
+/* -*- Mode: C; tab-width: 4; -*- */
+/*
+* Copyright (C) 2009, HustMoon Studio
+*
+* 文件名称:mystate.c
+* 摘 要:改变认证状态
+* 作 者:HustMoon@BYHH
+* 邮 箱:www.ehust@gmail.com
+*/
+#include "mystate.h"
+#include "myfunc.h"
+#include "dlfunc.h"
+#include
+#include
+#include
+
+#define MAX_SEND_COUNT 3 /* 最大超时次数 */
+
+volatile int state = ID_DISCONNECT; /* 认证状态 */
+const u_char *capBuf = NULL; /* 抓到的包 */
+static u_char sendPacket[0x3E8]; /* 用来发送的包 */
+static int sendCount = 0; /* 同一阶段发包计数 */
+
+extern const u_char STANDARD_ADDR[];
+extern char userName[];
+extern unsigned startMode;
+extern unsigned dhcpMode;
+extern u_char localMAC[], destMAC[];
+extern unsigned timeout;
+extern unsigned echoInterval;
+extern unsigned restartWait;
+extern char dhcpScript[];
+extern pcap_t *hPcap;
+extern u_char *fillBuf;
+extern unsigned fillSize;
+extern u_int32_t pingHost;
+#ifndef NO_ARP
+extern u_int32_t rip, gateway;
+extern u_char gateMAC[];
+static void sendArpPacket(); /* ARP监视 */
+#endif
+
+static void setTimer(unsigned interval); /* 设置定时器 */
+static int renewIP(); /* 更新IP */
+static void fillEtherAddr(u_int32_t protocol); /* 填充MAC地址和协议 */
+static int sendStartPacket(); /* 发送Start包 */
+static int sendIdentityPacket(); /* 发送Identity包 */
+static int sendChallengePacket(); /* 发送Md5 Challenge包 */
+static int sendEchoPacket(); /* 发送心跳包 */
+static int sendLogoffPacket(); /* 发送退出包 */
+static int waitEchoPacket(); /* 等候响应包 */
+
+static void setTimer(unsigned interval) /* 设置定时器 */
+{
+ struct itimerval timer;
+ timer.it_value.tv_sec = interval;
+ timer.it_value.tv_usec = 0;
+ timer.it_interval.tv_sec = interval;
+ timer.it_interval.tv_usec = 0;
+ setitimer(ITIMER_REAL, &timer, NULL);
+}
+
+int switchState(int type)
+{
+ if (state == type) /* 跟上次是同一状态? */
+ sendCount++;
+ else
+ {
+ state = type;
+ sendCount = 0;
+ }
+ if (sendCount>=MAX_SEND_COUNT && type!=ID_ECHO) /* 超时太多次? */
+ {
+ switch (type)
+ {
+ case ID_START:
+ printf("$! 找不到服务器,重启认证!\n");
+ break;
+ case ID_IDENTITY:
+ printf("$! 发送用户名超时,重启认证!\n");
+ break;
+ case ID_CHALLENGE:
+ printf("$! 发送密码超时,重启认证!\n");
+ break;
+ case ID_WAITECHO:
+ printf("$! 等候响应包超时,自行响应!\n");
+ fflush(stdout);
+ return switchState(ID_ECHO);
+ }
+ return restart();
+ }
+ switch (type)
+ {
+ case ID_DHCP:
+ return renewIP();
+ case ID_START:
+ return sendStartPacket();
+ case ID_IDENTITY:
+ return sendIdentityPacket();
+ case ID_CHALLENGE:
+ return sendChallengePacket();
+ case ID_WAITECHO: /* 塞尔的就不ping了,不好计时 */
+ return waitEchoPacket();
+ case ID_ECHO:
+ if (pingHost && sendCount*echoInterval > 60) { /* 1分钟左右 */
+ if (isOnline() == -1) {
+ printf("$! 认证掉线,开始重连!\n");
+ fflush(stdout);
+ return switchState(ID_START);
+ }
+ sendCount = 1;
+ }
+#ifndef NO_ARP
+ if (gateMAC[0] != 0xFE)
+ sendArpPacket();
+#endif
+ return sendEchoPacket();
+ case ID_DISCONNECT:
+ return sendLogoffPacket();
+ }
+ return 0;
+}
+
+int restart()
+{
+ if (startMode >= 3) /* 标记服务器地址为未获取 */
+ startMode -= 3;
+ state = ID_START;
+ sendCount = -1;
+ setTimer(restartWait); /* restartWait秒后或者服务器请求后重启认证 */
+ return 0;
+}
+
+static int renewIP()
+{
+ setTimer(0); /* 取消定时器 */
+ int count=0;
+ char* fip;
+ printf(">> 正在获取IP...\n");
+ fflush(stdout);
+ for(count=0;count<60;count++)
+ {
+ fip=formatIP(rip);
+ printf(">> 正在获取IP地址,当前IP:%s\n",fip);
+ fflush(stdout);
+ if((*fip)!=(char)127||(*fip)!=(char)169)break;
+ sleep(500);
+ }
+ printf(">> 操作结束,当前IP:%s\n",fip);
+ fflush(stdout);
+ if((*fip)==(char)127||(*fip)==(char)169) {
+ printf("!! 获取IP地址超时,认证将退出!");
+ fflush(stdout);
+ exit(EXIT_FAILURE);
+ }
+ dhcpMode += 3; /* 标记为已获取,123变为456,5不需再认证*/
+ if (fillHeader() == -1)
+ exit(EXIT_FAILURE);
+ if (dhcpMode == 5)
+ return switchState(ID_ECHO);
+ return switchState(ID_START);
+}
+
+static void fillEtherAddr(u_int32_t protocol)
+{
+ memset(sendPacket, 0, 0x3E8);
+ memcpy(sendPacket, destMAC, 6);
+ memcpy(sendPacket+0x06, localMAC, 6);
+ *(u_int32_t *)(sendPacket+0x0C) = htonl(protocol);
+}
+
+static int sendStartPacket()
+{
+ if (startMode%3 == 2) /* 赛尔 */
+ {
+ if (sendCount == 0)
+ {
+ printf(">> 寻找服务器...\n");
+ fflush(stdout);
+ memcpy(sendPacket, STANDARD_ADDR, 6);
+ memcpy(sendPacket+0x06, localMAC, 6);
+ *(u_int32_t *)(sendPacket+0x0C) = htonl(0x888E0101);
+ *(u_int16_t *)(sendPacket+0x10) = 0;
+ memset(sendPacket+0x12, 0xa5, 42);
+ setTimer(timeout);
+ }
+ return pcap_sendpacket(hPcap, sendPacket, 60);
+ }
+ if (sendCount == 0)
+ {
+ printf(">> 寻找服务器...\n");
+ fflush(stdout);
+ fillStartPacket();
+ fillEtherAddr(0x888E0101);
+ memcpy(sendPacket+0x12, fillBuf, fillSize);
+ setTimer(timeout);
+ }
+ return pcap_sendpacket(hPcap, sendPacket, 0x3E8);
+}
+
+static int sendIdentityPacket()
+{
+ int nameLen = strlen(userName);
+ if (startMode%3 == 2) /* 赛尔 */
+ {
+ if (sendCount == 0)
+ {
+ printf(">> 发送用户名...\n");
+ fflush(stdout);
+ *(u_int16_t *)(sendPacket+0x0E) = htons(0x0100);
+ *(u_int16_t *)(sendPacket+0x10) = *(u_int16_t *)(sendPacket+0x14) = htons(nameLen+30);
+ sendPacket[0x12] = 0x02;
+ sendPacket[0x16] = 0x01;
+ sendPacket[0x17] = 0x01;
+ fillCernetAddr(sendPacket);
+ memcpy(sendPacket+0x28, "03.02.05", 8);
+ memcpy(sendPacket+0x30, userName, nameLen);
+ setTimer(timeout);
+ }
+ sendPacket[0x13] = capBuf[0x13];
+ return pcap_sendpacket(hPcap, sendPacket, nameLen+48);
+ }
+ if (sendCount == 0)
+ {
+ printf(">> 发送用户名...\n");
+ fflush(stdout);
+ fillEtherAddr(0x888E0100);
+ nameLen = strlen(userName);
+ *(u_int16_t *)(sendPacket+0x14) = *(u_int16_t *)(sendPacket+0x10) = htons(nameLen+5);
+ sendPacket[0x12] = 0x02;
+ sendPacket[0x13] = capBuf[0x13];
+ sendPacket[0x16] = 0x01;
+ memcpy(sendPacket+0x17, userName, nameLen);
+ memcpy(sendPacket+0x17+nameLen, fillBuf, fillSize);
+ setTimer(timeout);
+ }
+ return pcap_sendpacket(hPcap, sendPacket, 0x3E8);
+}
+
+static int sendChallengePacket()
+{
+ int nameLen = strlen(userName);
+ if (startMode%3 == 2) /* 赛尔 */
+ {
+ if (sendCount == 0)
+ {
+ printf(">> 发送密码...\n");
+ fflush(stdout);
+ *(u_int16_t *)(sendPacket+0x0E) = htons(0x0100);
+ *(u_int16_t *)(sendPacket+0x10) = *(u_int16_t *)(sendPacket+0x14) = htons(nameLen+22);
+ sendPacket[0x12] = 0x02;
+ sendPacket[0x13] = capBuf[0x13];
+ sendPacket[0x16] = 0x04;
+ sendPacket[0x17] = 16;
+ memcpy(sendPacket+0x18, checkPass(capBuf[0x13], capBuf+0x18, capBuf[0x17]), 16);
+ memcpy(sendPacket+0x28, userName, nameLen);
+ setTimer(timeout);
+ }
+ return pcap_sendpacket(hPcap, sendPacket, nameLen+40);
+ }
+ if (sendCount == 0)
+ {
+ printf(">> 发送密码...\n");
+ fflush(stdout);
+ fillMd5Packet(capBuf+0x18);
+ fillEtherAddr(0x888E0100);
+ *(u_int16_t *)(sendPacket+0x14) = *(u_int16_t *)(sendPacket+0x10) = htons(nameLen+22);
+ sendPacket[0x12] = 0x02;
+ sendPacket[0x13] = capBuf[0x13];
+ sendPacket[0x16] = 0x04;
+ sendPacket[0x17] = 16;
+ memcpy(sendPacket+0x18, checkPass(capBuf[0x13], capBuf+0x18, capBuf[0x17]), 16);
+ memcpy(sendPacket+0x28, userName, nameLen);
+ memcpy(sendPacket+0x28+nameLen, fillBuf, fillSize);
+ setTimer(timeout);
+ }
+ return pcap_sendpacket(hPcap, sendPacket, 0x3E8);
+}
+
+static int sendEchoPacket()
+{
+ if (startMode%3 == 2) /* 赛尔 */
+ {
+ *(u_int16_t *)(sendPacket+0x0E) = htons(0x0106);
+ *(u_int16_t *)(sendPacket+0x10) = 0;
+ memset(sendPacket+0x12, 0xa5, 42);
+ switchState(ID_WAITECHO); /* 继续等待 */
+ return pcap_sendpacket(hPcap, sendPacket, 60);
+ }
+ if (sendCount == 0)
+ {
+ u_char echo[] =
+ {
+ 0x00,0x1E,0xFF,0xFF,0x37,0x77,0x7F,0x9F,0xFF,0xFF,0xD9,0x13,0xFF,0xFF,0x37,0x77,
+ 0x7F,0x9F,0xFF,0xFF,0xF7,0x2B,0xFF,0xFF,0x37,0x77,0x7F,0x3F,0xFF
+ };
+ printf(">< 发送心跳包以保持在线...\n");
+ printf("$$ 认证成功,当前IP地址: %s\n",formatIP(rip));
+ fflush(stdout);
+ fillEtherAddr(0x888E01BF);
+ memcpy(sendPacket+0x10, echo, sizeof(echo));
+ setTimer(echoInterval);
+ }
+ fillEchoPacket(sendPacket);
+ return pcap_sendpacket(hPcap, sendPacket, 0x2D);
+}
+
+static int sendLogoffPacket()
+{
+ setTimer(0); /* 取消定时器 */
+ if (startMode%3 == 2) /* 赛尔 */
+ {
+ *(u_int16_t *)(sendPacket+0x0E) = htons(0x0102);
+ *(u_int16_t *)(sendPacket+0x10) = 0;
+ memset(sendPacket+0x12, 0xa5, 42);
+ return pcap_sendpacket(hPcap, sendPacket, 60);
+ }
+ fillStartPacket(); /* 锐捷的退出包与Start包类似,不过其实不这样也是没问题的 */
+ fillEtherAddr(0x888E0102);
+ memcpy(sendPacket+0x12, fillBuf, fillSize);
+ return pcap_sendpacket(hPcap, sendPacket, 0x3E8);
+}
+
+static int waitEchoPacket()
+{
+ if (sendCount == 0)
+ setTimer(echoInterval);
+ return 0;
+}
+
+#ifndef NO_ARP
+static void sendArpPacket()
+{
+ u_char arpPacket[0x3C] = {
+ 0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x06,0x00,0x01,
+ 0x08,0x00,0x06,0x04,0x00};
+
+ if (gateMAC[0] != 0xFF) {
+ memcpy(arpPacket, gateMAC, 6);
+ memcpy(arpPacket+0x06, localMAC, 6);
+ arpPacket[0x15]=0x02;
+ memcpy(arpPacket+0x16, localMAC, 6);
+ memcpy(arpPacket+0x1c, &rip, 4);
+ memcpy(arpPacket+0x20, gateMAC, 6);
+ memcpy(arpPacket+0x26, &gateway, 4);
+ pcap_sendpacket(hPcap, arpPacket, 0x3C);
+ }
+ memset(arpPacket, 0xFF, 6);
+ memcpy(arpPacket+0x06, localMAC, 6);
+ arpPacket[0x15]=0x01;
+ memcpy(arpPacket+0x16, localMAC, 6);
+ memcpy(arpPacket+0x1c, &rip, 4);
+ memset(arpPacket+0x20, 0, 6);
+ memcpy(arpPacket+0x26, &gateway, 4);
+ pcap_sendpacket(hPcap, arpPacket, 0x2A);
+}
+#endif
diff --git a/CocoaMento-Src/mentohust-src/mystate.h b/CocoaMento-Src/mentohust-src/mystate.h
new file mode 100644
index 0000000..258d9b7
--- /dev/null
+++ b/CocoaMento-Src/mentohust-src/mystate.h
@@ -0,0 +1,22 @@
+/*
+* Copyright (C) 2009, HustMoon Studio
+*
+* 文件名称:mystate.h
+* 摘 要:改变认证状态
+* 作 者:HustMoon@BYHH
+*/
+#ifndef HUSTMOON_MYSTATE_H
+#define HUSTMOON_MYSTATE_H
+
+#define ID_DISCONNECT 0 /* 断开状态 */
+#define ID_START 1 /* 寻找服务器 */
+#define ID_IDENTITY 2 /* 发送用户名 */
+#define ID_CHALLENGE 3 /* 发送密码 */
+#define ID_ECHO 4 /* 发送心跳包 */
+#define ID_DHCP 5 /* 更新IP */
+#define ID_WAITECHO 6 /* 等待心跳包 */
+
+int switchState(int type); /* 改变状态 */
+int restart(); /* 重启认证 */
+
+#endif
diff --git a/CocoaMento-Src/mentohust-src/types.h b/CocoaMento-Src/mentohust-src/types.h
new file mode 100644
index 0000000..b3dfdcd
--- /dev/null
+++ b/CocoaMento-Src/mentohust-src/types.h
@@ -0,0 +1,10 @@
+#ifndef TYPES_H
+#define TYPES_H
+typedef unsigned char *POINTER;
+typedef unsigned char BYTE;
+typedef unsigned char UCHAR;
+typedef unsigned short int WORD;
+typedef int LONG;
+typedef unsigned int DWORD;
+typedef unsigned int UINT4;
+#endif
diff --git a/CocoaMento-Src/mentothread.cpp b/CocoaMento-Src/mentothread.cpp
new file mode 100644
index 0000000..2f15b3b
--- /dev/null
+++ b/CocoaMento-Src/mentothread.cpp
@@ -0,0 +1,93 @@
+#include "mentothread.h"
+#include
+#include
+
+QProcess* pr;
+
+MentoThread::MentoThread(QSettings* settings) :
+ QThread(0)
+{
+ this->settings=settings;
+ connect(this,SIGNAL(terminated()),this,SLOT(terminatedHandle()));
+ //connect(this,SIGNAL(error(QString)),this,SLOT(terminate()));
+ //pr->moveToThread(this);
+}
+
+void MentoThread::processFinished(int status, QProcess::ExitStatus qstatus)
+{
+ if(qstatus==QProcess::CrashExit) emit processCrashed();
+ else if(status!=0) emit error(tr("%d").setNum(status));
+ else emit exitSuccess();
+}
+
+
+void MentoThread::run()
+{
+ pr=new QProcess();
+ pr->setWorkingDirectory(tr("%1/Contents/MacOS/").arg(tr(CocoaInitialize::mainBundlePath())));
+ pr->start(tr("./mentohust"));
+ if(!pr->waitForStarted(3000))
+ {
+ emit startFailure();
+ delete pr;
+ return;
+ }
+ while(pr->state()==QProcess::Running)
+ {
+ if(pr->waitForReadyRead(100))
+ {
+ while(pr->canReadLine())
+ {
+ QString out(pr->readLine());
+ emit output(out);
+ if(out.at(0)=='$') emit notify(out.mid(3));
+ else if(out.at(0)=='>')
+ {
+ emit statusChanged(out.mid(3),(out.at(1)=='<')?2:0);
+ if(out.at(1)=='!') emit exitSuccess();
+ }
+ else if(out.at(0)=='!')
+ {
+
+ if(settings->value(tr("AllowError")).toBool())
+ {
+ emit statusChanged(out.mid(3),1);
+ continue;
+ }
+ if(out.at(1)=='%') emit noConfig();
+ else emit error(out.mid(3));
+ return;
+ }
+ else if(out.at(0)=='~') emit authError();
+ }
+ }
+ }
+
+}
+
+void MentoThread::terminate()
+{
+ if(pr==NULL){
+ QThread::terminate();
+ return;
+ }
+ pr->terminate();
+ pr->waitForFinished();
+ pr->close();
+
+ if(pr->exitCode()==0||pr->exitStatus()==QProcess::NormalExit)
+ emit exitSuccess();
+ else emit error(tr("%d").setNum(pr->exitStatus()));
+ QThread::terminate();
+
+ //pr->thread()->terminate();
+}
+
+void MentoThread::terminatedHandle()
+{
+ delete pr;
+}
+
+MentoThread::~MentoThread(){
+ this->terminate();
+}
diff --git a/CocoaMento-Src/mentothread.h b/CocoaMento-Src/mentothread.h
new file mode 100644
index 0000000..113c19c
--- /dev/null
+++ b/CocoaMento-Src/mentothread.h
@@ -0,0 +1,35 @@
+#ifndef MENTOTHREAD_H
+#define MENTOTHREAD_H
+
+#include
+#include
+#include
+
+class MentoThread : public QThread
+{
+ Q_OBJECT
+public:
+ explicit MentoThread(QSettings * settings);
+ void run();
+ ~MentoThread();
+
+signals:
+ void processCrashed();
+ void output(QString str);
+ void notify(QString str);
+ void successNotify();
+ void statusChanged(QString str,int status);
+ void error(QString errdetail);
+ void exitSuccess();
+ void startFailure();
+ void authError();
+ void noConfig();
+public slots:
+ void terminate();
+ void terminatedHandle();
+ void processFinished(int status,QProcess::ExitStatus qstatus);
+private:
+ QSettings * settings;
+};
+
+#endif // MENTOTHREAD_H
diff --git a/CocoaMento-Src/menu.h b/CocoaMento-Src/menu.h
new file mode 100644
index 0000000..bf16f69
--- /dev/null
+++ b/CocoaMento-Src/menu.h
@@ -0,0 +1,19 @@
+#ifndef MENU_H
+#define MENU_H
+
+
+class Menu
+{
+public:
+ Menu(const char * title=0);
+ void* cocoaMenuRef();
+ void addMenuItem(void* item);
+ void addMenuSeparator();
+ ~Menu();
+
+private:
+ class CocoaMenuBridge;
+ CocoaMenuBridge* b;
+};
+
+#endif // MENU_H
diff --git a/CocoaMento-Src/menu.mm b/CocoaMento-Src/menu.mm
new file mode 100644
index 0000000..b5b59a2
--- /dev/null
+++ b/CocoaMento-Src/menu.mm
@@ -0,0 +1,42 @@
+#include "menu.h"
+#include "menuitem.h"
+#import
+
+class Menu::CocoaMenuBridge
+{
+ public:
+ NSMenu* menu;
+};
+
+Menu::Menu(const char *title)
+{
+ b=new CocoaMenuBridge();
+ if(title==0) title="";
+ b->menu=[[NSMenu alloc] initWithTitle:[NSString stringWithUTF8String: title]];
+ if(title!=0){
+ [b->menu addItemWithTitle:[NSString stringWithUTF8String: title] action:nil keyEquivalent:@""];
+ [[b->menu itemAtIndex:0] setEnabled:NO];
+ }
+ [b->menu setAutoenablesItems: NO];
+ [b->menu retain];
+}
+
+void Menu::addMenuItem(void *item)
+{
+ [b->menu addItem:((NSMenuItem * )((MenuItem*)item)->cocoaMenuItemRef())];
+}
+void Menu::addMenuSeparator()
+{
+ [b->menu addItem:[NSMenuItem separatorItem]];
+}
+
+void* Menu::cocoaMenuRef()
+{
+ return (void*) b->menu;
+}
+
+Menu::~Menu()
+{
+ [b->menu release];
+ delete b;
+}
diff --git a/CocoaMento-Src/menuitem.h b/CocoaMento-Src/menuitem.h
new file mode 100644
index 0000000..4391bc1
--- /dev/null
+++ b/CocoaMento-Src/menuitem.h
@@ -0,0 +1,37 @@
+//
+// menubridge.h
+// HelloCocoa
+//
+// Created by 云尔 on 11-3-29.
+// Copyright 2011年 __MyCompanyName__. All rights reserved.
+//
+
+
+
+
+#ifndef _MENU_ITEM_H
+#define _MENU_ITEM_H
+
+#include
+#include "cocoamenuitemvirtual.h"
+#include "menu.h"
+
+class MenuItem:public CocoaMenuItemVirtual
+{
+public:
+ MenuItem(const char* title);
+ void * cocoaMenuItemRef();
+ void setTitle(const char * title);
+ void setEnable(bool isEnable);
+ void setSubMenu(Menu* m);
+ bool isEnable();
+ ~MenuItem();
+
+private:
+ class MenuItemCocoaBridge;
+ // class QtBridge;
+ MenuItemCocoaBridge * b;
+};
+
+
+#endif
diff --git a/CocoaMento-Src/menuitem.mm b/CocoaMento-Src/menuitem.mm
new file mode 100644
index 0000000..a881c0e
--- /dev/null
+++ b/CocoaMento-Src/menuitem.mm
@@ -0,0 +1,104 @@
+//
+// cocoamenuitem.m
+// HelloCocoa
+//
+// Created by 云尔 on 11-3-29.
+// Copyright 2011年 __MyCompanyName__. All rights reserved.
+//
+
+#include "menuitem.h"
+
+#import
+
+@interface cocoamenuitem : NSMenuItem {
+ @public
+ CocoaMenuItemVirtual * p;
+
+}
+
+-(void) setWarp:(CocoaMenuItemVirtual* ) b;
+-(IBAction) trigger:(id)sender;
+
+@end
+
+@implementation cocoamenuitem
+
+- (id)init
+{
+ self = [super init];
+ if (self) {
+ // Initialization code here.
+ [self setTarget:self];
+ [self setAction:@selector(trigger:)];
+ }
+
+ return self;
+}
+- (void) setWarp:(CocoaMenuItemVirtual*) base
+{
+ self->p = base;
+}
+
+- (IBAction) trigger:(id)sender
+{
+ if(self->p) self->p->doTrigger();
+}
+
+
+- (void)dealloc
+{
+ [super dealloc];
+}
+
+@end
+
+class MenuItem::MenuItemCocoaBridge
+{
+public:
+ cocoamenuitem * item;
+};
+
+MenuItem::MenuItem(const char * title)
+{
+ CocoaMenuItemVirtual();
+ b=new MenuItemCocoaBridge();
+ b->item=[[cocoamenuitem alloc] init ];
+ setTitle(title);
+ [b->item setWarp:this];
+ [b->item retain];
+}
+
+void MenuItem::setTitle(const char* title)
+{
+ [b->item setTitle:[NSString stringWithUTF8String:title]];
+}
+
+void* MenuItem::cocoaMenuItemRef()
+{
+ return (void *) this->b->item;
+}
+
+void MenuItem::setEnable(bool isEnable)
+{
+ if(isEnable) [b->item setEnabled:YES];
+ else [b->item setEnabled:NO];
+}
+
+bool MenuItem::isEnable()
+{
+ if([b->item isEnabled]==NO) return false;
+ return true;
+}
+
+void MenuItem::setSubMenu(Menu *m)
+{
+ if(m!=0){
+ [b->item setSubmenu:(NSMenu*)m->cocoaMenuRef()];
+ }
+}
+
+MenuItem::~MenuItem()
+{
+ [b->item release];
+ delete b;
+}
diff --git a/CocoaMento-Src/menuviewitem.h b/CocoaMento-Src/menuviewitem.h
new file mode 100644
index 0000000..c95a422
--- /dev/null
+++ b/CocoaMento-Src/menuviewitem.h
@@ -0,0 +1,19 @@
+#ifndef MENUVIEWITEM_H
+#define MENUVIEWITEM_H
+
+#include
+#include "menuitem.h"
+
+class MenuViewItem : public MenuItem
+{
+public:
+ MenuViewItem(const char* title=0,QMacNativeWidget* qw=0);
+ void setWidget(QMacNativeWidget * qw);
+ void hideView();
+ void showView();
+ ~MenuViewItem();
+private:
+ QWidget * w;
+};
+
+#endif // MENUVIEWITEM_H
diff --git a/CocoaMento-Src/menuviewitem.mm b/CocoaMento-Src/menuviewitem.mm
new file mode 100644
index 0000000..2bf2c2f
--- /dev/null
+++ b/CocoaMento-Src/menuviewitem.mm
@@ -0,0 +1,34 @@
+#include "menuviewitem.h"
+
+#import "Cocoa/Cocoa.h"
+
+MenuViewItem::MenuViewItem(const char *title, QMacNativeWidget *qw):MenuItem(title)
+{
+ this->setTitle(title);
+ setWidget(qw);
+}
+
+void MenuViewItem::setWidget(QMacNativeWidget *qw){
+ this->w=qw;
+ showView();
+}
+
+void MenuViewItem::showView()
+{
+ if(this->w!=0) {
+ [(NSMenuItem*)this->cocoaMenuItemRef() setView:(reinterpret_cast(this->w->winId()))];
+ this->w->show();
+ }
+ else{
+ hideView();
+ }
+}
+
+void MenuViewItem::hideView()
+{
+ [(NSMenuItem*)this->cocoaMenuItemRef() setView:nil];
+}
+
+MenuViewItem::~MenuViewItem()
+{
+}
diff --git a/CocoaMento-Src/qtport.cpp b/CocoaMento-Src/qtport.cpp
new file mode 100644
index 0000000..60d3042
--- /dev/null
+++ b/CocoaMento-Src/qtport.cpp
@@ -0,0 +1,13 @@
+#include "qtport.h"
+
+QtPort::QtPort(QObject *parent) :
+ QObject(parent)
+{
+}
+void QtPort::emitEvent()
+{
+ emit trigger();
+}
+
+
+
diff --git a/CocoaMento-Src/qtport.h b/CocoaMento-Src/qtport.h
new file mode 100644
index 0000000..4b4747c
--- /dev/null
+++ b/CocoaMento-Src/qtport.h
@@ -0,0 +1,17 @@
+#ifndef QTPORT_H
+#define QTPORT_H
+
+#include
+
+class QtPort : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QtPort(QObject *parent = 0);
+ void emitEvent();
+signals:
+ void trigger();
+
+};
+
+#endif // QTPORT_H
diff --git a/CocoaMento-Src/statusicon.mm b/CocoaMento-Src/statusicon.mm
new file mode 100644
index 0000000..998e132
--- /dev/null
+++ b/CocoaMento-Src/statusicon.mm
@@ -0,0 +1,60 @@
+#include "statusicon.h"
+
+
+#import
+
+
+
+class StatusIcon::CocoaBridge
+{
+ public:
+ NSStatusItem * statusicon;
+
+};
+
+
+StatusIcon::StatusIcon()
+{
+ b=new StatusIcon::CocoaBridge();
+ b->statusicon=[[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
+ setHighlightMode(true);
+}
+
+void StatusIcon::showIcon()
+{
+ this->setIcon("normal.png");
+}
+
+void StatusIcon::setIcon(const char *name)
+{
+ [b->statusicon setImage:[NSImage imageNamed:[NSString stringWithUTF8String: name]]];
+}
+
+void StatusIcon::setHighlightMode(bool highlight)
+{
+ if(highlight) [b->statusicon setHighlightMode:YES];
+ else [b->statusicon setHighlightMode:NO];
+}
+
+bool StatusIcon::highlightMode()
+{
+ if([b->statusicon highlightMode]==NO) return false;
+ return true;
+}
+
+void StatusIcon::hideIcon()
+{
+ [b->statusicon setImage:nil];
+}
+
+void StatusIcon::setMenu(Menu *menu)
+{
+ this->menu=menu;
+ [b->statusicon setMenu:(NSMenu*) menu->cocoaMenuRef()];
+}
+
+
+StatusIcon::~StatusIcon(){
+ [b->statusicon release];
+ delete b;
+}